<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
  <meta name="theme-color" content="#222">
  <meta name="generator" content="Hexo 4.2.1">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#222">
  <link rel="stylesheet" href="/css/main.css">
  <link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
  <link rel="stylesheet" href="/lib/pace/pace-theme-minimal.min.css">
  <script src="/lib/pace/pace.min.js"></script>
  <script id="hexo-configurations">
    var NexT = window.NexT ||
    {};
    var CONFIG = {
      "hostname": "cuiqingcai.com",
      "root": "/",
      "scheme": "Pisces",
      "version": "7.8.0",
      "exturl": false,
      "sidebar":
      {
        "position": "right",
        "width": 360,
        "display": "post",
        "padding": 18,
        "offset": 12,
        "onmobile": false,
        "widgets": [
          {
            "type": "image",
            "name": "阿布云",
            "enable": false,
            "url": "https://www.abuyun.com/http-proxy/introduce.html",
            "src": "https://qiniu.cuiqingcai.com/88au8.jpg",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "天验",
            "enable": true,
            "url": "https://tutorial.lengyue.video/?coupon=12ef4b1a-a3db-11ea-bb37-0242ac130002_cqx_850",
            "src": "https://qiniu.cuiqingcai.com/bco2a.png",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "华为云",
            "enable": false,
            "url": "https://activity.huaweicloud.com/2020_618_promotion/index.html?bpName=5f9f98a29e2c40b780c1793086f29fe2&bindType=1&salesID=wangyubei",
            "src": "https://qiniu.cuiqingcai.com/y42ik.jpg",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "张小鸡",
            "enable": false,
            "url": "http://www.zxiaoji.com/",
            "src": "https://qiniu.cuiqingcai.com/fm72f.png",
            "width": "100%"
      },
          {
            "type": "image",
            "name": "Luminati",
            "src": "https://qiniu.cuiqingcai.com/ikkq9.jpg",
            "url": "https://luminati-china.io/?affiliate=ref_5fbbaaa9647883f5c6f77095",
            "width": "100%",
            "enable": false
      },
          {
            "type": "image",
            "name": "IPIDEA",
            "url": "http://www.ipidea.net/?utm-source=cqc&utm-keyword=?cqc",
            "src": "https://qiniu.cuiqingcai.com/0ywun.png",
            "width": "100%",
            "enable": true
      },
          {
            "type": "tags",
            "name": "标签云",
            "enable": true
      },
          {
            "type": "categories",
            "name": "分类",
            "enable": true
      },
          {
            "type": "friends",
            "name": "友情链接",
            "enable": true
      },
          {
            "type": "hot",
            "name": "猜你喜欢",
            "enable": true
      }]
      },
      "copycode":
      {
        "enable": true,
        "show_result": true,
        "style": "mac"
      },
      "back2top":
      {
        "enable": true,
        "sidebar": false,
        "scrollpercent": true
      },
      "bookmark":
      {
        "enable": false,
        "color": "#222",
        "save": "auto"
      },
      "fancybox": false,
      "mediumzoom": false,
      "lazyload": false,
      "pangu": true,
      "comments":
      {
        "style": "tabs",
        "active": "gitalk",
        "storage": true,
        "lazyload": false,
        "nav": null,
        "activeClass": "gitalk"
      },
      "algolia":
      {
        "hits":
        {
          "per_page": 10
        },
        "labels":
        {
          "input_placeholder": "Search for Posts",
          "hits_empty": "We didn't find any results for the search: ${query}",
          "hits_stats": "${hits} results found in ${time} ms"
        }
      },
      "localsearch":
      {
        "enable": true,
        "trigger": "auto",
        "top_n_per_article": 10,
        "unescape": false,
        "preload": false
      },
      "motion":
      {
        "enable": false,
        "async": false,
        "transition":
        {
          "post_block": "bounceDownIn",
          "post_header": "slideDownIn",
          "post_body": "slideDownIn",
          "coll_header": "slideLeftIn",
          "sidebar": "slideUpIn"
        }
      },
      "path": "search.xml"
    };

  </script>
  <meta name="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
  <meta property="og:type" content="website">
  <meta property="og:title" content="静觅">
  <meta property="og:url" content="https://cuiqingcai.com/page/4/index.html">
  <meta property="og:site_name" content="静觅">
  <meta property="og:description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
  <meta property="og:locale" content="zh_CN">
  <meta property="article:author" content="崔庆才">
  <meta property="article:tag" content="崔庆才">
  <meta property="article:tag" content="静觅">
  <meta property="article:tag" content="PHP">
  <meta property="article:tag" content="Java">
  <meta property="article:tag" content="Python">
  <meta property="article:tag" content="Spider">
  <meta property="article:tag" content="爬虫">
  <meta property="article:tag" content="Web">
  <meta property="article:tag" content="Kubernetes">
  <meta property="article:tag" content="深度学习">
  <meta property="article:tag" content="机器学习">
  <meta property="article:tag" content="数据分析">
  <meta property="article:tag" content="网络">
  <meta property="article:tag" content="IT">
  <meta property="article:tag" content="技术">
  <meta property="article:tag" content="博客">
  <meta name="twitter:card" content="summary">
  <link rel="canonical" href="https://cuiqingcai.com/page/4/">
  <script id="page-configurations">
    // https://hexo.io/docs/variables.html
    CONFIG.page = {
      sidebar: "",
      isHome: true,
      isPost: false,
      lang: 'zh-CN'
    };

  </script>
  <title>静觅丨崔庆才的个人站点</title>
  <meta name="google-site-verification" content="p_bIcnvirkFzG2dYKuNDivKD8-STet5W7D-01woA2fc" />
  <noscript>
    <style>
      .use-motion .brand,
      .use-motion .menu-item,
      .sidebar-inner,
      .use-motion .post-block,
      .use-motion .pagination,
      .use-motion .comments,
      .use-motion .post-header,
      .use-motion .post-body,
      .use-motion .collection-header
      {
        opacity: initial;
      }

      .use-motion .site-title,
      .use-motion .site-subtitle
      {
        opacity: initial;
        top: initial;
      }

      .use-motion .logo-line-before i
      {
        left: initial;
      }

      .use-motion .logo-line-after i
      {
        right: initial;
      }

    </style>
  </noscript>
  <link rel="alternate" href="/atom.xml" title="静觅" type="application/atom+xml">
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container">
    <div class="headband"></div>
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner">
        <div class="site-brand-container">
          <div class="site-nav-toggle">
            <div class="toggle" aria-label="切换导航栏">
              <span class="toggle-line toggle-line-first"></span>
              <span class="toggle-line toggle-line-middle"></span>
              <span class="toggle-line toggle-line-last"></span>
            </div>
          </div>
          <div class="site-meta">
            <a href="/" class="brand" rel="start">
              <span class="logo-line-before"><i></i></span>
              <h1 class="site-title">静觅 <span class="site-subtitle"> 崔庆才的个人站点 </span>
              </h1>
              <span class="logo-line-after"><i></i></span>
            </a>
          </div>
          <div class="site-nav-right">
            <div class="toggle popup-trigger">
              <i class="fa fa-search fa-fw fa-lg"></i>
            </div>
          </div>
        </div>
        <nav class="site-nav">
          <ul id="menu" class="main-menu menu">
            <li class="menu-item menu-item-home">
              <a href="/" rel="section">首页</a>
            </li>
            <li class="menu-item menu-item-archives">
              <a href="/archives/" rel="section">文章列表</a>
            </li>
            <li class="menu-item menu-item-tags">
              <a href="/tags/" rel="section">文章标签</a>
            </li>
            <li class="menu-item menu-item-categories">
              <a href="/categories/" rel="section">文章分类</a>
            </li>
            <li class="menu-item menu-item-about">
              <a href="/about/" rel="section">关于博主</a>
            </li>
            <li class="menu-item menu-item-message">
              <a href="/message/" rel="section">给我留言</a>
            </li>
            <li class="menu-item menu-item-search">
              <a role="button" class="popup-trigger">搜索 </a>
            </li>
          </ul>
        </nav>
        <div class="search-pop-overlay">
          <div class="popup search-popup">
            <div class="search-header">
              <span class="search-icon">
                <i class="fa fa-search"></i>
              </span>
              <div class="search-input-container">
                <input autocomplete="off" autocapitalize="off" placeholder="搜索..." spellcheck="false" type="search" class="search-input">
              </div>
              <span class="popup-btn-close">
                <i class="fa fa-times-circle"></i>
              </span>
            </div>
            <div id="search-result">
              <div id="no-result">
                <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
              </div>
            </div>
          </div>
        </div>
      </div>
    </header>
    <div class="back-to-top">
      <i class="fa fa-arrow-up"></i>
      <span>0%</span>
    </div>
    <div class="reading-progress-bar"></div>
    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div class="content index posts-expand">
            <div class="carousel">
              <div id="wowslider-container">
                <div class="ws_images">
                  <ul>
                    <li><a target="_blank" href="https://cuiqingcai.com/5052.html"><img title="Python3网络爬虫开发实战教程" src="https://qiniu.cuiqingcai.com/ipy96.jpg" /></a></li>
                    <li><a target="_blank" href="https://t.lagou.com/fRCBRsRCSN6FA"><img title="52讲轻松搞定网络爬虫" src="https://qiniu.cuiqingcai.com/fqq5e.png" /></a></li>
                    <li><a target="_blank" href="https://brightdata.grsm.io/cuiqingcai"><img title="亮网络解锁器" src="https://qiniu.cuiqingcai.com/6qnb7.png" /></a></li>
                    <li><a target="_blank" href="https://cuiqingcai.com/4320.html"><img title="Python3网络爬虫开发视频教程" src="https://qiniu.cuiqingcai.com/bjrny.jpg" /></a></li>
                    <li><a target="_blank" href="https://cuiqingcai.com/5094.html"><img title="爬虫代理哪家强？十大付费代理详细对比评测出炉！" src="https://qiniu.cuiqingcai.com/nifs6.jpg" /></a></li>
                  </ul>
                </div>
                <div class="ws_thumbs">
                  <div>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/ipy96.jpg" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/fqq5e.png" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/6qnb7.png" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/bjrny.jpg" /></a>
                    <a target="_blank" href="#"><img src="https://qiniu.cuiqingcai.com/nifs6.jpg" /></a>
                  </div>
                </div>
                <div class="ws_shadow"></div>
              </div>
            </div>
            <link rel="stylesheet" href="/lib/wowslide/slide.css">
            <script src="/lib/wowslide/jquery.min.js"></script>
            <script src="/lib/wowslide/slider.js"></script>
            <script>
              jQuery("#wowslider-container").wowSlider(
              {
                effect: "cube",
                prev: "",
                next: "",
                duration: 20 * 100,
                delay: 20 * 100,
                width: 716,
                height: 297,
                autoPlay: true,
                playPause: true,
                stopOnHover: false,
                loop: false,
                bullets: 0,
                caption: true,
                captionEffect: "slide",
                controls: true,
                onBeforeStep: 0,
                images: 0
              });

            </script>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/31039.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 安装配置 <i class="label-arrow"></i>
                  </a>
                  <a href="/31039.html" class="post-title-link" itemprop="url">lxml 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>lxml 是 Python 的一个解析库，支持 HTML 和 XML 的解析，支持 XPath 解析方式，而且解析效率非常高，本节我们了解下它的安装方式，分为 Windows、Linux、Mac 三大平台来介绍。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>官方网站：<a href="http://lxml.de" target="_blank" rel="noopener">http://lxml.de</a></li>
                    <li>GitHub：<a href="https://github.com/lxml/lxml" target="_blank" rel="noopener">https://github.com/lxml/lxml</a></li>
                    <li>PyPi：<a href="https://pypi.python.org/pypi/lxml" target="_blank" rel="noopener">https://pypi.python.org/pypi/lxml</a></li>
                  </ul>
                  <h2 id="安装方法"><a href="#安装方法" class="headerlink" title="安装方法"></a>安装方法</h2>
                  <h3 id="Windows-下的安装"><a href="#Windows-下的安装" class="headerlink" title="Windows 下的安装"></a>Windows 下的安装</h3>
                  <p>Windows 下可以先尝试利用 pip3 安装，直接执行如下命令即可：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> lxml</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果没有任何报错则证明安装成功。</p>
                  <p>如果出现报错，比如提示缺少 libxml2 库等信息，可以采用 wheel 方式安装。</p>
                  <p>推荐直接到这里下载对应的 wheel 文件，链接为：<a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml" target="_blank" rel="noopener">http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml</a>，找到本地安装 Python 版本和系统对应的 lxml 版本，例如 Windows 64 位 Python3.6 就选择 lxml‑3.8.0‑cp36‑cp36m‑win_amd64.whl，以此类推，将其下载到本地。</p>
                  <p>然后利用 pip3 安装即可，命令如下：</p>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">pip3</span> <span class="selector-tag">install</span> <span class="selector-tag">lxml</span>‑3<span class="selector-class">.8</span><span class="selector-class">.0</span>‑<span class="selector-tag">cp36</span>‑<span class="selector-tag">cp36m</span>‑<span class="selector-tag">win_amd64</span><span class="selector-class">.whl</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样我们就可以成功安装好 lxml 了。</p>
                  <h3 id="Linux-下的安装"><a href="#Linux-下的安装" class="headerlink" title="Linux 下的安装"></a>Linux 下的安装</h3>
                  <p>在 Linux 平台下安装问题不大，同样可以先尝试 pip3 安装，命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> lxml</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果报错，可以尝试下方的解决方案。</p>
                  <h4 id="CentOS、RedHat"><a href="#CentOS、RedHat" class="headerlink" title="CentOS、RedHat"></a>CentOS、RedHat</h4>
                  <p>对于此类系统，报错主要是因为缺少必要的库。</p>
                  <p>执行如下命令安装所需的库即可：</p>
                  <figure class="highlight gml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo yum groupinstall -<span class="symbol">y</span> development tools</span><br><span class="line">sudo yum install -<span class="symbol">y</span> epel-release libxslt-devel libxml2-devel openssl-devel</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>主要是 libxslt-devel libxml2-devel 这两个库，lxml 依赖于它们。安装好了之后重新尝试 Pip 安装即可。</p>
                  <h4 id="Ubuntu、Debian、Deepin"><a href="#Ubuntu、Debian、Deepin" class="headerlink" title="Ubuntu、Debian、Deepin"></a>Ubuntu、Debian、Deepin</h4>
                  <p>报错的原因同样可能是缺少了必要的类库，执行如下命令安装：</p>
                  <figure class="highlight q">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="built_in">get</span> install -y python3-<span class="built_in">dev</span> build-essential libssl-<span class="built_in">dev</span> libffi-<span class="built_in">dev</span> libxml2 libxml2-<span class="built_in">dev</span> libxslt1-<span class="built_in">dev</span> zlib1g-<span class="built_in">dev</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>安装好了之后重新尝试 pip 安装即可。</p>
                  <h3 id="Mac-下的安装"><a href="#Mac-下的安装" class="headerlink" title="Mac 下的安装"></a>Mac 下的安装</h3>
                  <p>在 Mac 平台下，仍然可以首先尝试 pip3 安装，命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> lxml</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果产生错误，可以执行如下命令将必要的类库安装：</p>
                  <figure class="highlight ada">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">xcode-<span class="keyword">select</span> <span class="comment">--install</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>之后再重新运行 pip3 安装就没有问题了。</p>
                  <p>lxml 是一个非常重要的库，比如 BeautifulSoup、Scrapy 框架都需要用到此库，所以请一定安装成功。</p>
                  <h2 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h2>
                  <p>安装完成之后，可以在 Python 命令行下测试。</p>
                  <figure class="highlight ruby">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line"><span class="meta">&gt;&gt;</span>&gt; import lxml</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果没有错误报出，则证明库已经安装好了。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-03 02:39:41" itemprop="dateCreated datePublished" datetime="2021-10-03T02:39:41+08:00">2021-10-03</time>
                </span>
                <span id="/31039.html" class="post-meta-item leancloud_visitors" data-flag-title="lxml 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.3k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/31038.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 安装配置 <i class="label-arrow"></i>
                  </a>
                  <a href="/31038.html" class="post-title-link" itemprop="url">Flask 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>Flask 是一个轻量级的 Web 服务程序，简单、易用、灵活，在本书中我们主要用它来做一些 API 服务，本节我们来了解下它的安装方式。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>GitHub：<a href="https://github.com/pallets/flask" target="_blank" rel="noopener">https://github.com/pallets/flask</a></li>
                    <li>官方文档：<a href="http://flask.pocoo.org" target="_blank" rel="noopener">http://flask.pocoo.org</a></li>
                    <li>中文文档：<a href="http://docs.jinkan.org/docs/flask" target="_blank" rel="noopener">http://docs.jinkan.org/docs/flask</a></li>
                    <li>PyPi：<a href="https://pypi.python.org/pypi/Flask" target="_blank" rel="noopener">https://pypi.python.org/pypi/Flask</a></li>
                  </ul>
                  <h2 id="pip-安装"><a href="#pip-安装" class="headerlink" title="pip 安装"></a>pip 安装</h2>
                  <p>推荐使用 pip 安装，命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> flask</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行完毕之后就可以完成安装。</p>
                  <h2 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h2>
                  <p>安装成功之后可以运行如下实例代码测试一下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask</span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route("/")</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">hello</span><span class="params">()</span>:</span></span><br><span class="line">    <span class="keyword">return</span> <span class="string">"Hello World!"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line">    app.run()</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>直接运行代码，可以发现系统会在 5000 端口开启 Web 服务，控制台输出如下：</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">* Running <span class="keyword">on</span> http://<span class="number">127.0</span>.<span class="number">0.1</span>:<span class="number">5000</span>/ (Press CTRL+C <span class="keyword">to</span> <span class="keyword">quit</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>直接访问：<a href="http://127.0.0.1:5000/" target="_blank" rel="noopener">http://127.0.0.1:5000/</a>，可以观察到网页中呈现了 Hello World!，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/3ssou.png" alt=""></p>
                  <p>这样一个最简单的 Flask 程序就运行成功了。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-03 00:39:41" itemprop="dateCreated datePublished" datetime="2021-10-03T00:39:41+08:00">2021-10-03</time>
                </span>
                <span id="/31038.html" class="post-meta-item leancloud_visitors" data-flag-title="Flask 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>579</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/31034.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 安装配置 <i class="label-arrow"></i>
                  </a>
                  <a href="/31034.html" class="post-title-link" itemprop="url">requests 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>本节介绍下 Python 常用爬虫库 requests 的安装方式。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>GitHub：<a href="https://github.com/requests/requests" target="_blank" rel="noopener">https://github.com/requests/requests</a></li>
                    <li>PyPy：<a href="https://pypi.python.org/pypi/requests" target="_blank" rel="noopener">https://pypi.python.org/pypi/requests</a></li>
                    <li>官方文档：<a href="http://www.python-requests.org" target="_blank" rel="noopener">http://www.python-requests.org</a></li>
                    <li>中文文档：<a href="http://docs.python-requests.org/zh_CN/latest" target="_blank" rel="noopener">http://docs.python-requests.org/zh_CN/latest</a></li>
                  </ul>
                  <h2 id="安装方法"><a href="#安装方法" class="headerlink" title="安装方法"></a>安装方法</h2>
                  <h3 id="pip-安装"><a href="#pip-安装" class="headerlink" title="pip 安装"></a>pip 安装</h3>
                  <p>无论是 Windows、Linux 还是 Mac，都可以通过 pip 这个包管理工具来安装。</p>
                  <p>在命令行下运行如下命令即可完成 requests 库的安装：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> requests</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这是最简单的安装方式，推荐此种方法安装。</p>
                  <h3 id="wheel-安装"><a href="#wheel-安装" class="headerlink" title="wheel 安装"></a>wheel 安装</h3>
                  <p>wheel 是 Python 的一种安装包，其后缀为 whl，在网速较差的情况下可以选择下载下 wheel 文件再安装，直接用 pip3 命令加文件名安装即可。</p>
                  <p>不过在这之前需要先安装 wheel 库，安装命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> wheel</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后到 PyPi 上下载对应的 wheel 文件，如当前最新版本为 2.17.3，则打开：<a href="https://pypi.python.org/pypi/requests/2.17.3#downloads" target="_blank" rel="noopener">https://pypi.python.org/pypi/requests/2.17.3#downloads</a>，下载 requests-2.17.3-py2.py3-none-any.whl 到本地。</p>
                  <p>随后命令行进入 Wheel 文件目录，利用 pip 安装即可。</p>
                  <figure class="highlight css">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="selector-tag">pip3</span> <span class="selector-tag">install</span> <span class="selector-tag">requests-2</span><span class="selector-class">.17</span><span class="selector-class">.3-py2</span><span class="selector-class">.py3-none-any</span><span class="selector-class">.whl</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样我们同样可以完成 requests 的安装。</p>
                  <h3 id="源码安装"><a href="#源码安装" class="headerlink" title="源码安装"></a>源码安装</h3>
                  <p>那么如果你不想用 pip 来安装，或者想获取某一特定版本，可以选择下载源码安装。</p>
                  <p>此种方式需要先找到此库的源码地址，然后下载下来再用命令安装。</p>
                  <p>requests 项目的地址是：<a href="https://github.com/kennethreitz/requests" target="_blank" rel="noopener">https://github.com/kennethreitz/requests</a>。</p>
                  <p>可以通过 Git 来下载源代码：</p>
                  <figure class="highlight crmsh">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">git <span class="keyword">clone</span> <span class="title">git</span>://github.com/kennethreitz/requests.git</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>或通过 curl 下载：</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">curl -OL https:<span class="regexp">//gi</span>thub.com<span class="regexp">/kennethreitz/</span>requests<span class="regexp">/tarball/m</span>aster</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>下载下来之后，进入目录，执行如下命令安装即可：</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">cd</span> requests</span><br><span class="line"><span class="keyword">python3</span> setup.<span class="keyword">py</span> install</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>命令执行结束后即可完成 requests 的安装，由于此种安装方式比较繁琐，后文此种安装方式不再赘述。</p>
                  <h2 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h2>
                  <p>为了验证库是否已经安装成功，可以在命令行下测试一下：</p>
                  <figure class="highlight ruby">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line"><span class="meta">&gt;&gt;</span>&gt; import requests</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>在命令行首先输入 python3，进入命令行模式，然后输入如上内容，如果什么错误提示也没有，那么就证明我们已经成功安装了 requests。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-02 21:39:41" itemprop="dateCreated datePublished" datetime="2021-10-02T21:39:41+08:00">2021-10-02</time>
                </span>
                <span id="/31034.html" class="post-meta-item leancloud_visitors" data-flag-title="requests 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.2k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/31030.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 安装配置 <i class="label-arrow"></i>
                  </a>
                  <a href="/31030.html" class="post-title-link" itemprop="url">BeautifulSoup 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>BeautifulSoup 是 Python 的一个 HTML 或 XML 的解析库，我们可以用它来方便地从网页中提取数据，它拥有强大的 API 和多样的解析方式，本节我们了解下它的安装方式。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>官方文档：<a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc" target="_blank" rel="noopener">https://www.crummy.com/software/BeautifulSoup/bs4/doc</a></li>
                    <li>中文文档：<a href="https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh" target="_blank" rel="noopener">https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh</a></li>
                    <li>PyPi：<a href="https://pypi.python.org/pypi/beautifulsoup4" target="_blank" rel="noopener">https://pypi.python.org/pypi/beautifulsoup4</a></li>
                  </ul>
                  <h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2>
                  <p>BeautifulSoup 的 HTML 和 XML 解析器是依赖于 lxml 库的，所以在此之前请确保已经成功安装好了 lxml 库，具体的安装方式参见 lxml 的安装：<a href="https://setup.scrape.center/lxml" target="_blank" rel="noopener">https://setup.scrape.center/lxml</a>。</p>
                  <h2 id="安装方法"><a href="#安装方法" class="headerlink" title="安装方法"></a>安装方法</h2>
                  <h3 id="pip-安装"><a href="#pip-安装" class="headerlink" title="pip 安装"></a>pip 安装</h3>
                  <p>目前 BeautifulSoup 的最新版本是 4.x 版本，之前的版本已经停止开发了，推荐使用 pip3 来安装，安装命令如下：</p>
                  <figure class="highlight smali">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 install beautifulsoup4</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>命令执行完毕之后即可完成安装。</p>
                  <h3 id="wheel-安装"><a href="#wheel-安装" class="headerlink" title="wheel 安装"></a>wheel 安装</h3>
                  <p>当然也可以从 PyPi 下载 wheel 文件安装，链接如下：<br><a href="https://pypi.python.org/pypi/beautifulsoup4" target="_blank" rel="noopener">https://pypi.python.org/pypi/beautifulsoup4</a></p>
                  <p>然后 pip3 安装 Wheel 文件即可。</p>
                  <h2 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h2>
                  <p>安装完成之后可以运行下方的代码验证一下。</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">from</span> bs4 <span class="keyword">import</span> BeautifulSoup</span><br><span class="line">soup = BeautifulSoup(<span class="string">'&lt;p&gt;Hello&lt;/p&gt;'</span>, <span class="string">'lxml'</span>)</span><br><span class="line">print(soup.p.string)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果：</p>
                  <figure class="highlight ebnf">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attribute">Hello</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果运行结果一致则证明安装成功。</p>
                  <p>注意在这里我们虽然安装的是 beautifulsoup4 这个包，但是在引入的时候是引入的 bs4，这是因为这个包源代码本身的库文件夹名称就是 bs4，所以安装完成之后，这个库文件夹就被移入到我们本机 Python3 的 lib 库里，所以识别到的库文件名称就叫做 bs4，所以我们引入的时候就引入 bs4 这个包。</p>
                  <p>因此，包本身的名称和我们使用时导入的包的名称并不一定是一致的。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-02 19:39:41" itemprop="dateCreated datePublished" datetime="2021-10-02T19:39:41+08:00">2021-10-02</time>
                </span>
                <span id="/31030.html" class="post-meta-item leancloud_visitors" data-flag-title="BeautifulSoup 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>906</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/31056.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 安装配置 <i class="label-arrow"></i>
                  </a>
                  <a href="/31056.html" class="post-title-link" itemprop="url">aiohttp 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>之前我们介绍的 requests 库是一个阻塞式 HTTP 请求库，当我们发出一个请求后，程序会一直等待服务器的响应，直到得到响应后程序才会进行下一步的处理，其实这个过程是比较耗费资源的。如果程序可以在这个等待过程中做一些其他的事情，如进行请求的调度、响应的处理等等，那么爬取效率一定会大大提高。</p>
                  <p>Aiohttp 就是这样一个提供异步 Web 服务的库，从 Python3.5 版本开始，Python 中加入了 async/await 关键字，使得回调的写法更加直观和人性化，Aiohttp 的异步操作借助于 async/await 关键字写法变得更加简洁，架构更加清晰。使用异步请求库来进行数据抓取会大大提高效率，下面我们来看一下这个库的安装方法。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>官方文档：<a href="http://aiohttp.readthedocs.io/en/stable" target="_blank" rel="noopener">http://aiohttp.readthedocs.io/en/stable</a></li>
                    <li>GitHub：<a href="https://github.com/aio-libs/aiohttp" target="_blank" rel="noopener">https://github.com/aio-libs/aiohttp</a></li>
                    <li>PyPi：<a href="https://pypi.python.org/pypi/aiohttp" target="_blank" rel="noopener">https://pypi.python.org/pypi/aiohttp</a></li>
                  </ul>
                  <h2 id="pip-安装"><a href="#pip-安装" class="headerlink" title="pip 安装"></a>pip 安装</h2>
                  <p>推荐使用 pip 安装，命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> aiohttp</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>另外官方还推荐安装如下两个库，一个是字符编码检测库 cchardet，另一个是加速 DNS 解析库 aiodns，安装命令如下：</p>
                  <figure class="highlight cmake">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 <span class="keyword">install</span> cchardet aiodns</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h2 id="测试安装"><a href="#测试安装" class="headerlink" title="测试安装"></a>测试安装</h2>
                  <p>安装完成之后，可以在 Python 命令行下测试。</p>
                  <figure class="highlight ruby">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line"><span class="meta">&gt;&gt;</span>&gt; import aiohttp</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果没有错误报出，则证明库已经安装好了。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-02 18:29:41" itemprop="dateCreated datePublished" datetime="2021-10-02T18:29:41+08:00">2021-10-02</time>
                </span>
                <span id="/31056.html" class="post-meta-item leancloud_visitors" data-flag-title="aiohttp 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>647</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30035.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Python <i class="label-arrow"></i>
                  </a>
                  <a href="/30035.html" class="post-title-link" itemprop="url">Python3 的安装</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>本节会介绍 Windows、Linux、Mac 三大平台下安装 Python3 的过程。</p>
                  <h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2>
                  <ul>
                    <li>官方网站：<a href="http://python.org" target="_blank" rel="noopener">http://python.org</a></li>
                    <li>下载地址：<a href="https://www.python.org/downloads" target="_blank" rel="noopener">https://www.python.org/downloads</a></li>
                    <li>第三方库：<a href="https://pypi.python.org/pypi" target="_blank" rel="noopener">https://pypi.python.org/pypi</a></li>
                    <li>官方文档：<a href="https://docs.python.org/3" target="_blank" rel="noopener">https://docs.python.org/3</a></li>
                    <li>中文教程：<a href="http://www.runoob.com/python3/python3-tutorial.html" target="_blank" rel="noopener">http://www.runoob.com/python3/python3-tutorial.html</a></li>
                    <li>Awesome Python：<a href="https://github.com/vinta/awesome-python" target="_blank" rel="noopener">https://github.com/vinta/awesome-python</a></li>
                    <li>Awesome Python 中文版：<a href="https://github.com/jobbole/awesome-python-cn" target="_blank" rel="noopener">https://github.com/jobbole/awesome-python-cn</a></li>
                  </ul>
                  <h2 id="Windows-下的安装"><a href="#Windows-下的安装" class="headerlink" title="Windows 下的安装"></a>Windows 下的安装</h2>
                  <p>Windows 下安装 Python3 的方式有两种，一种是通过 Anaconda 安装，Anaconda 提供了 Python 的科学计算环境，里面自带了 Python 以及常用的库，如果选用了此种方式后面的环境配置方式会更加简便，另一种是直接下载安装包安装，即标准的安装方式。下面会依次介绍这两种安装方式，任选其一即可。</p>
                  <h3 id="Anaconda-安装"><a href="#Anaconda-安装" class="headerlink" title="Anaconda 安装"></a>Anaconda 安装</h3>
                  <p>Anaconda 的 官方下载链接为：<a href="https://www.anaconda.com/products/individual，选择" target="_blank" rel="noopener">https://www.anaconda.com/products/individual，选择</a> Windows 版本的安装包下载即可，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/7j6wj.png" alt="image-20211002155805295"></p>
                  <p>如果下载速度过慢可以选择使用清华大学镜像，下载列表链接为：<a href="https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/" target="_blank" rel="noopener">https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/</a>，使用说明链接为：<a href="https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/" target="_blank" rel="noopener">https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/</a>，可以选择需要的版本进行下载，速度相比官网会快很多。</p>
                  <p>下载完成之后直接双击运行安装包安装即可，安装完成之后 Python3 的环境就配置好了。</p>
                  <h3 id="安装包安装"><a href="#安装包安装" class="headerlink" title="安装包安装"></a>安装包安装</h3>
                  <p>推荐直接下载可执行文件安装包安装，到官方网站下载 Python3 安装包。</p>
                  <p><a href="https://www.python.org/downloads/" target="_blank" rel="noopener">https://www.python.org/downloads/</a></p>
                  <p>到目前为止，Python 的最新版本是 3.9.7，如果想安装特定的 Python 版本，可以查看网页下方的内容，看到各个 Python 安装包的发布历史，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/0chje.png" alt="image-20211002160003693"></p>
                  <p><strong>由于一些库的兼容性问题，个人比较推荐安装 Python 3.6 或 3.7 版本，而非 3.8、3.9 版本。</strong></p>
                  <p>Python 3.6 版本安装包的下载链接为：<a href="https://www.python.org/downloads/release/python-368/，Python" target="_blank" rel="noopener">https://www.python.org/downloads/release/python-368/，Python</a> 3.7 版本安装包的下载链接为：<a href="https://www.python.org/downloads/release/python-379/，打开之后可以看到如下下载列表：" target="_blank" rel="noopener">https://www.python.org/downloads/release/python-379/，打开之后可以看到如下下载列表：</a></p>
                  <p><img src="https://qiniu.cuiqingcai.com/7gtwf.png" alt="image-20211002160607143"></p>
                  <p>64 位系统可以下载 Windows x86-64 executable installer，32 位系统可以下载 Windows x86 executable installer。</p>
                  <p>下载完成之后，直接双击运行 Python 安装包，使用图形界面安装，设置好 Python 的安装路径，完成后将 Python3 和 Python3 的 Scripts 目录配置到环境变量即可。</p>
                  <p>环境变量的配置，此处以 Win10 系统为例进行演示。</p>
                  <p>假如我安装后的 Python3 路径为 C:\Python36，从资源管理器中打开该路径，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/8ueif.jpg" alt=""></p>
                  <p>将该路径复制下来。</p>
                  <p>随后打开电脑-属性，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/9985s.jpg" alt=""></p>
                  <p>点击左侧的高级系统设置，即可看到在弹出的窗口中下方有环境变量按钮，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/4uaji.jpg" alt=""></p>
                  <p>点击环境变量，找到系统变量下的 Path 变量，随后点击编辑按钮，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/0otlu.jpg" alt=""></p>
                  <p>随后点击新建，新建一个条目，将刚才拷贝的 C:\Python36 复制进去，当然此处的路径就是你的 Python3 安装目录，请自行替换，然后再把 C:\Python36\Scripts 路径复制进去，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/laonf.jpg" alt=""></p>
                  <p>最后点击确定即可完成环境变量的配置。</p>
                  <p>配置好环境变量之后，我们就可以直接在命令行直接执行环境变量路径下的可执行文件了，如 python、pip 等命令。</p>
                  <h3 id="添加别名"><a href="#添加别名" class="headerlink" title="添加别名"></a>添加别名</h3>
                  <p>以上两种安装方式任选其一即可完成安装，但如果我们之前安装过 Python2 的话，可能会导致版本冲突问题，比如在命令行下输入 python 就不知道是调用的 Python2 还是 Python3 了，为了解决这个问题，建议将安装目录中的 python.exe 复制一份，命名为 python3.exe，这样便可以调用 python3 命令了，实际上和 python 命令是完全一致的，这样可以更好地区分 Python 版本，当然如果没有安装过 Python2 的话也建议添加此别名，添加完毕之后如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/gfhlj.jpg" alt=""></p>
                  <p>对于 pip 来说，安装包中自带了 pip3.exe 可执行文件，我们也可以直接使用 pip3 命令，无需额外配置。</p>
                  <h3 id="测试验证"><a href="#测试验证" class="headerlink" title="测试验证"></a>测试验证</h3>
                  <p>安装完成之后我们可以通过命令行测试一下安装是否成功，在开始菜单搜索 cmd，找到命令提示符，就进入了命令行模式，输入 python 测试一下能否成功调用 python，如果添加了别名的话可以输入 python3 测试，在这里输入的是 python3，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/q5gkm.jpg" alt=""></p>
                  <p>类似输出结果如下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line">Python <span class="number">3.6</span><span class="number">.1</span> (v3<span class="number">.6</span><span class="number">.1</span>:<span class="number">69</span>c0db5, Mar <span class="number">21</span> <span class="number">2017</span>, <span class="number">17</span>:<span class="number">54</span>:<span class="number">52</span>) [MSC v<span class="number">.1900</span> <span class="number">32</span> bit (Intel)] on win32</span><br><span class="line">Type <span class="string">"help"</span>, <span class="string">"copyright"</span>, <span class="string">"credits"</span> <span class="keyword">or</span> <span class="string">"license"</span> <span class="keyword">for</span> more information.</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>print(<span class="string">'Hello World'</span>)</span><br><span class="line">Hello World</span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span>exit()</span><br><span class="line">$ pip3 -V</span><br><span class="line">pip <span class="number">9.0</span><span class="number">.1</span> <span class="keyword">from</span> c:\python36\lib\site-packages (python <span class="number">3.6</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果出现类似上面的提示，则证明 Python3 和 pip3 均安装成功，如果提示命令不存在，那么请检查下环境变量的配置情况。</p>
                  <h2 id="Linux-下的安装"><a href="#Linux-下的安装" class="headerlink" title="Linux 下的安装"></a>Linux 下的安装</h2>
                  <p>Linux 下安装方式有多种，命令安装、源码安装、Anaconda 安装。</p>
                  <p>使用源码安装需要自行编译，时间较长。推荐使用系统自带命令或 Anaconda 安装，简单高效。在这里对各种安装方式分别予以讲解。</p>
                  <h3 id="命令行安装"><a href="#命令行安装" class="headerlink" title="命令行安装"></a>命令行安装</h3>
                  <p>不同的 Linux 发行版本安装方式又有不同，在此分别予以介绍。</p>
                  <h4 id="CentOS、RedHat"><a href="#CentOS、RedHat" class="headerlink" title="CentOS、RedHat"></a>CentOS、RedHat</h4>
                  <p>如果是 CentOS 或 RedHat 版本，使用 yum 命令安装即可。</p>
                  <figure class="highlight gml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo yum update -<span class="symbol">y</span></span><br><span class="line">sudo yum install -<span class="symbol">y</span> python3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <h4 id="Ubuntu、Debian、Deepin"><a href="#Ubuntu、Debian、Deepin" class="headerlink" title="Ubuntu、Debian、Deepin"></a>Ubuntu、Debian、Deepin</h4>
                  <p>首先安装 Python3，使用 apt-get 安装即可，在安装前还需安装一些基础库，命令如下：</p>
                  <figure class="highlight q">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="built_in">get</span> install -y python3-<span class="built_in">dev</span> build-essential libssl-<span class="built_in">dev</span> libffi-<span class="built_in">dev</span> libxml2 libxml2-<span class="built_in">dev</span> libxslt1-<span class="built_in">dev</span> zlib1g-<span class="built_in">dev</span> libcurl4-openssl-<span class="built_in">dev</span></span><br><span class="line">sudo apt-<span class="built_in">get</span> install -y python3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>执行完如上命令之后就可以成功安装好 Python3 了。</p>
                  <p>然后还需要安装 pip3，仍然使用 apt-get 安装即可，命令如下：</p>
                  <figure class="highlight routeros">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo apt-<span class="builtin-name">get</span> install -y python3-pip</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>执行完毕之后便可以成功安装 Python3 及 pip3。</p>
                  <h3 id="源码安装"><a href="#源码安装" class="headerlink" title="源码安装"></a>源码安装</h3>
                  <p>如果命令行安装方式有问题，还可以下载 Python3 源码进行安装。</p>
                  <p>源码下载地址为：<a href="https://www.python.org/ftp/python/" target="_blank" rel="noopener">https://www.python.org/ftp/python/</a>，可以自行选用想要的版本进行安装，在此以 Python3.6.2 为例进行说明，安装路径设置为 /usr/local/python3。</p>
                  <p>首先创建安装目录，命令如下：</p>
                  <figure class="highlight maxima">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo <span class="built_in">mkdir</span> /usr/<span class="built_in">local</span>/python3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>随后下载安装包并解压进入，命令如下：</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">wget --no-check-certificate https:<span class="comment">//www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz</span></span><br><span class="line">tar -xzvf Python<span class="number">-3.6</span><span class="number">.2</span>.tgz</span><br><span class="line">cd Python<span class="number">-3.6</span><span class="number">.2</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>接下来编译安装，所需时间可能较长，请耐心等待，命令如下：</p>
                  <figure class="highlight gauss">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo ./configure --prefix=/usr/<span class="keyword">local</span>/python3</span><br><span class="line">sudo <span class="built_in">make</span></span><br><span class="line">sudo <span class="built_in">make</span> install</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>安装完成之后创建 Python3 链接，命令如下：</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo ln -s <span class="regexp">/usr/</span>local<span class="regexp">/python3/</span>bin<span class="regexp">/python3 /u</span>sr<span class="regexp">/bin/</span>python3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>随后下载 Pip 安装包并安装，命令如下：</p>
                  <figure class="highlight vim">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">wget --<span class="keyword">no</span>-check-certificate http<span class="variable">s:</span>//github.<span class="keyword">com</span>/pypa/pip/archive/<span class="number">9.0</span>.<span class="number">1</span>.tar.gz</span><br><span class="line">tar -xzvf <span class="number">9.0</span>.<span class="number">1</span>.tar.gz</span><br><span class="line"><span class="keyword">cd</span> pip-<span class="number">9.0</span>.<span class="number">1</span></span><br><span class="line"><span class="keyword">python3</span> setup.<span class="keyword">py</span> install</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>安装完成后再创建 Pip3 链接，命令如下：</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">sudo ln -s <span class="regexp">/usr/</span>local<span class="regexp">/python3/</span>bin<span class="regexp">/pip /u</span>sr<span class="regexp">/bin/</span>pip3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样就成功安装好了 Python3 及 pip3。</p>
                  <h3 id="Anaconda-安装-1"><a href="#Anaconda-安装-1" class="headerlink" title="Anaconda 安装"></a>Anaconda 安装</h3>
                  <p>Anaconda 同样支持 Linux，Anaconda 的官方下载链接为：<a href="https://www.anaconda.com/products/individual，选择对应版本的安装包下载即可。如果下载速度过慢同样可以使用清华镜像，参考" target="_blank" rel="noopener">https://www.anaconda.com/products/individual，选择对应版本的安装包下载即可。如果下载速度过慢同样可以使用清华镜像，参考</a> Windows 部分的介绍，在此不再赘述。</p>
                  <h3 id="测试验证-1"><a href="#测试验证-1" class="headerlink" title="测试验证"></a>测试验证</h3>
                  <p>命令行测试 Python3 和 pip3 是否安装成功。</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line">Python <span class="number">3.6</span>.<span class="number">2</span> (default, Nov <span class="number">17</span> <span class="number">2017</span>, <span class="number">17</span>:<span class="number">05</span>:<span class="number">23</span>)</span><br><span class="line">Type <span class="string">"help"</span>, <span class="string">"copyright"</span>, <span class="string">"credits"</span> or <span class="string">"license"</span> <span class="keyword">for</span> more information.</span><br><span class="line">&gt;&gt;&gt; <span class="keyword">exit</span>()</span><br><span class="line">$ pip3 -V</span><br><span class="line">pip <span class="number">8.1</span>.<span class="number">1</span> from <span class="regexp">/usr/</span>lib<span class="regexp">/python3/</span>dist-packages (python <span class="number">3.6</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如出现类似上面的提示，则证明 Python3 和 pip3 安装成功。</p>
                  <h2 id="Mac-下的安装"><a href="#Mac-下的安装" class="headerlink" title="Mac 下的安装"></a>Mac 下的安装</h2>
                  <p>在 Mac 下同样有多种安装方式，如 Homebrew、安装包安装、Anaconda 安装等，推荐使用 Homebrew 安装。</p>
                  <h3 id="Homebrew-安装"><a href="#Homebrew-安装" class="headerlink" title="Homebrew 安装"></a>Homebrew 安装</h3>
                  <p>Homebrew 是 Mac 平台下强大的包管理工具，首先安装 Homebrew，官方网站是：<a href="https://brew.sh/" target="_blank" rel="noopener">https://brew.sh/</a>。</p>
                  <p>执行如下命令即可安装 Homebrew：</p>
                  <figure class="highlight sql">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/<span class="keyword">install</span>/<span class="keyword">master</span>/<span class="keyword">install</span>)<span class="string">"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>安装完成后便可以使用 brew 命令安装 Python3 和 pip3 了。</p>
                  <p>如果要安装 Python3 的最新版本，可以直接运行如下命令：</p>
                  <figure class="highlight mipsasm">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">brew </span><span class="keyword">install </span>python3</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p><strong>由于一些库的兼容性问题，个人比较推荐安装 Python 3.6 或 3.7 版本，而非 3.8、3.9 版本。</strong></p>
                  <p>所以这里如果要安装 Python3.7 版本，可以运行如下命令：</p>
                  <figure class="highlight angelscript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">brew install <span class="symbol">python@</span><span class="number">3.7</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>命令执行完成之后发现 Python3 和 pip3 均已经安装成功。</p>
                  <h3 id="安装包安装-1"><a href="#安装包安装-1" class="headerlink" title="安装包安装"></a>安装包安装</h3>
                  <p>可以到官方网站下载 Python3 安装包。链接为：<a href="https://www.python.org/downloads/" target="_blank" rel="noopener"></a>。</p>
                  <p><strong>由于一些库的兼容性问题，个人比较推荐安装 Python 3.6 或 3.7 版本，而非 3.8、3.9 版本。</strong></p>
                  <p>Python 3.6 版本安装包的下载链接为：<a href="https://www.python.org/downloads/release/python-368/，Python" target="_blank" rel="noopener">https://www.python.org/downloads/release/python-368/，Python</a> 3.7 版本安装包的下载链接为：<a href="https://www.python.org/downloads/release/python-379/，打开之后可以看到如下下载列表：" target="_blank" rel="noopener">https://www.python.org/downloads/release/python-379/，打开之后可以看到如下下载列表：</a></p>
                  <p><img src="https://qiniu.cuiqingcai.com/l6itb.png" alt=""></p>
                  <p>可以选择下载 Mac OS X 64-bit installer，下载完成之后打开安装包按照提示安装即可，安装完毕之后 Python 相关的环境变量就配置好了。</p>
                  <h3 id="Anaconda-安装-2"><a href="#Anaconda-安装-2" class="headerlink" title="Anaconda 安装"></a>Anaconda 安装</h3>
                  <p>Anaconda 同样支持 Mac，Anaconda 的官方下载链接为：<a href="https://www.anaconda.com/products/individual，选择" target="_blank" rel="noopener">https://www.anaconda.com/products/individual，选择</a> Python3 版本的安装包下载即可，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/t8qmm.png" alt=""></p>
                  <p>如果下载速度过慢同样可以使用清华镜像，参考 Windows 部分的介绍，在此不再赘述。</p>
                  <h3 id="测试验证-2"><a href="#测试验证-2" class="headerlink" title="测试验证"></a>测试验证</h3>
                  <p>命令行测试 Python3 和 pip3 是否安装成功。</p>
                  <figure class="highlight awk">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">$ python3</span><br><span class="line">Python <span class="number">3.6</span>.<span class="number">2</span> (default, Nov <span class="number">17</span> <span class="number">2017</span>, <span class="number">17</span>:<span class="number">05</span>:<span class="number">23</span>)</span><br><span class="line">Type <span class="string">"help"</span>, <span class="string">"copyright"</span>, <span class="string">"credits"</span> or <span class="string">"license"</span> <span class="keyword">for</span> more information.</span><br><span class="line">&gt;&gt;&gt; <span class="keyword">exit</span>()</span><br><span class="line">$ pip3 -V</span><br><span class="line">pip <span class="number">8.1</span>.<span class="number">1</span> from <span class="regexp">/usr/</span>lib<span class="regexp">/python3/</span>dist-packages (python <span class="number">3.6</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如出现类似上面的提示，则证明 Python3 和 pip3 安装成功。</p>
                  <h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2>
                  <p>本节介绍了三大平台 Windows、Linux、Mac 下 Python3 的安装方式，如有疑问欢迎留言。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-10-02 13:39:41" itemprop="dateCreated datePublished" datetime="2021-10-02T13:39:41+08:00">2021-10-02</time>
                </span>
                <span id="/30035.html" class="post-meta-item leancloud_visitors" data-flag-title="Python3 的安装" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>5.4k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>5 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30034.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 个人日记 <i class="label-arrow"></i>
                  </a>
                  <a href="/30034.html" class="post-title-link" itemprop="url">意外收获了一些好听的歌单</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>今天搜歌的时候，发现因为版权问题，网易云和 QQ 音乐都搜不到，说酷狗上能搜到，于是我就把之前好久不用的酷狗音乐下载回来了。</p>
                  <p>不太记得从什么时候开始用网易云音乐听歌的了，好像是从大学的时候，自从用了网易云之后，酷狗就被我渐渐抛弃了。因为好久不用了，我都不太记得我的账号密码是什么了。</p>
                  <p>但抱着试一试的心态，我尝试登录了一下。</p>
                  <p>结果居然登录成功了！</p>
                  <p>然后我就发现了我好久之前收藏过的一些歌，这里截个图啦：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/ik20d.png" alt=""></p>
                  <p>图里面的这个歌单是 14 年创建的，当时我还记得当时听酷狗音乐的时候，我喜欢玩 QQ 飞车这个游戏，喜欢边听歌边开赛车，为了速度与激情，当时我还专门搜集了好多比较动感的音乐，具体名字其实我也不关心，其实到现在我也分不清哪首歌究竟是谁唱的或者或歌名叫什么。但当时觉得就是好听，一气搜集了好多。</p>
                  <p>那个时候，我还很喜欢听河图、许嵩、汪苏泷、徐良等人的歌，暴露了哈哈哈，当时我还专门为他们创建了歌单。另外当时还有一些网络情歌、dj 土嗨歌也感觉不错，所以当时就加入到我的收藏里面了。</p>
                  <p>于是今天我就在挨个听我之前收藏的音乐，感觉每一首歌都是那么亲切！而且个个都是我喜欢的（毕竟是之前收藏过的）！有的歌，听的时候都勾起了我当时玩飞车驰骋赛场时候的画面，那种感觉，真的好亲切而又舒服。</p>
                  <p>不知道这个怎么解释，这种感觉，就像出门在外好久之后回到家的感觉，许久未见的老友见面的感觉，这些歌里面承载着满满的青春和回忆。</p>
                  <p>我不知道大家有没有之前也用过其他的一些音乐软件，比如说你也可能前几年用过酷狗、酷我、QQ 音乐、网易云，但是现在已经换了其他的音乐软件了。</p>
                  <p>如果是这样的话，我推荐大家尝试着找一找之前自己用过的音乐软件的账号，把它下载回来，听听自己之前收藏过的歌单，每个人都有每个人的青春和故事，听着自己喜欢过的老歌，一定是一番别样的感觉。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-09-14 09:50:22" itemprop="dateCreated datePublished" datetime="2021-09-14T09:50:22+08:00">2021-09-14</time>
                </span>
                <span id="/30034.html" class="post-meta-item leancloud_visitors" data-flag-title="意外收获了一些好听的歌单" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>778</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30033.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> HTML <i class="label-arrow"></i>
                  </a>
                  <a href="/30033.html" class="post-title-link" itemprop="url">分享一个不错的前端组件库</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>我对设计美学有一定执念，所以我在编写一些 UI 的时候会比较注重它的一些美观度、舒适度。</p>
                  <p>随着现在前端的发展，一些成套的组件库也是层出不穷了，比如基于 Vue 的 Element UI、iView，基于 React 的 Ant Design、Fluent UI 等等，它们设计其实挺好的，但有一些色彩搭配和风格还没有达到我理想中的样子。</p>
                  <p>我其实比较欣赏苹果的那种半透明设计风，比如这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/9ot8l.png" alt=""></p>
                  <p>大家感兴趣可以看苹果的设计手册：<a href="https://developer.apple.com/design/human-interface-guidelines/" target="_blank" rel="noopener">https://developer.apple.com/design/human-interface-guidelines/</a></p>
                  <p>同时我也对 Material Design 中的一些光影理念比较推崇，但并不太喜欢原生的 Material Design，比如这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/zszdg.png" alt=""></p>
                  <p>我个人觉得这种原生的 Material Design 有点用力过猛，显得有些沉重。</p>
                  <p>相比之下，目前的一些 Element UI、Ant Design 则算是吸收了二者的一些优点，提供了一些 UI 组件，比如这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/xi5zm.png" alt=""></p>
                  <p>这种设计风格显得没有 Material Design 那样厚重，也吸取了一些 Apple Design 的风格，另外一些光影效果拿捏也挺不错的。</p>
                  <p>然而，这些设计还是没有达到我理想中的样子。</p>
                  <p>比如说，卡片的一些设计、边缘轮廓的一些设计，总让我感觉没有那么清爽。</p>
                  <p>后来，直到我用了一款梯🪜子软件，它是基于一个叫做 STISLA 的 UI 框架设计的，整体风格是这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/3cvy5.png" alt=""></p>
                  <p><img src="https://qiniu.cuiqingcai.com/goh10.png" alt=""></p>
                  <p>一眼看过去，爱了爱了，看起来，它借鉴了 Material Design 的一些光影设计理念，同时又不显得那么厚重，一些布局、卡片和文本框的轮廓也显得很明晰，另外一些配色、图标的样式整体也给人一种清爽的感觉，总之我个人非常喜欢。</p>
                  <p>这个 UI 框架的名字叫做 STISLA，其官网是： <a href="https://getstisla.com/" target="_blank" rel="noopener">https://getstisla.com/</a>，它是基于 BootStrap4 编写的，很可惜的是，它现在没有提供 Vue、React 的支持，所以使用起来暂时还不能完全组件化，不过里面的一些 class 可以直接拿来用，就像使用 tailwind 一样。</p>
                  <p>STISLA 现在是完全开源的，其 GitHub 仓库是：<a href="https://github.com/stisla/stisla" target="_blank" rel="noopener">https://github.com/stisla/stisla</a>，使用的话直接引用其中的 CSS 即可，这里就不再赘述了。</p>
                  <p>另外关于更多的组件，大家可以到官方 Demo 示例页面来体验，链接是：<a href="https://demo.getstisla.com/index.html" target="_blank" rel="noopener">https://demo.getstisla.com/index.html</a>，这里简单列举几个组件。</p>
                  <p>头像：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/gejjc.png" alt=""></p>
                  <p>文章列表：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/98u54.png" alt=""></p>
                  <p>统计图表：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/lun68.png" alt=""></p>
                  <p>用户信息：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/j5o4j.png" alt=""></p>
                  <p>表单：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/69gqd.png" alt=""></p>
                  <p>表格：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/02fje.png" alt=""></p>
                  <p>不得不说，每个版面我都觉得非常赏心悦目！感兴趣的就去官网看看吧。</p>
                  <p>好啦，以上就介绍这么多啦，大家感兴趣的话就快快用起来吧～</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-09-13 09:50:22" itemprop="dateCreated datePublished" datetime="2021-09-13T09:50:22+08:00">2021-09-13</time>
                </span>
                <span id="/30033.html" class="post-meta-item leancloud_visitors" data-flag-title="分享一个不错的前端组件库" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.1k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30032.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 个人日记 <i class="label-arrow"></i>
                  </a>
                  <a href="/30032.html" class="post-title-link" itemprop="url">理解了，但写不出来</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>最近看了一些书，学到了一些知识和方法论，比如说看刘未鹏的《暗时间》，就学到了很多知识。</p>
                  <p>读完之后，收获非常大，于是我决定把其中的一些感想写出来。</p>
                  <p>首先自然而然的就是有关暗时间的解释了，比如什么是暗时间，怎么来利用暗时间，就是我前面发的那篇文章。</p>
                  <p>虽然整体上看起来这篇文章的中心思想非常简单，我当时看书的时候也体会到了其中的一些中心思想，但等我真的要把这个写成一篇文章或者感想的时候，我却发现我却想不出一个好的定义，好的引入的例子，我原本以为我能非常流畅地把这篇文章写下来的，但真的到写的时候才发现我并没有做好准备，又去翻看了一下原书才写出来。</p>
                  <p>通过这件事，我就反思到了两件事：</p>
                  <ul>
                    <li>
                      <p>我需要利用好自己的暗时间来思考。</p>
                    </li>
                    <li>
                      <p>读一本书，不去复盘和思考，收效甚微。</p>
                    </li>
                  </ul>
                  <p>对于第一点。比如我在写文章之前，我应该先构思好我这篇文章的整体脉络，比如怎么引入、怎么说明、怎么结尾等等，这些思考其实平常就可以做的，比如我在下班路上、我在洗漱的时候、我在吃饭的时候，就完全可以拿这个时间来思考，思考不出来的，记下来再去翻看下，看看人家作者是怎么把这个观点表达出来的，作者的思路是怎样的。只有思考过了，脑中有大致的脉络，到时候真的写的时候就变得非常流畅了。而如果平时不加思考，只有写作的时候才去思考，有时候写作效率就会比较低。虽然写作也能帮助很好地思考，真的写不出来的时候再去构思和翻看未尝不可，但总体来说，这样不会比平时也思考的结果来的更好。</p>
                  <p>对于第二点。有时候我看完一本书，不去复盘和思考，只是泛泛地看完，看完就丢在一边再也不打开，其实收效是非常小的。一本书，往往是一个人几年甚至几十年的精华总结，组织很调理而且完整。相比网上一些碎片化的文章、博客、问答，一本书的价值简直大太多了。读书，自然就要理会到其中作者为我们传达的知识、思想，我们不是为了读书而读书，读书是和作者在心灵层次上的交流，要真的理会到作者的传达的意思，我们往往是需要多去思考、多去复盘、多去实践的。因为，这些知识的形成，也都是作者历经了很多实践和思考换来的，如果我们只是浮光掠影地过一遍，不多去思考和复盘，收效往往并不大。</p>
                  <p>所以说，这件事让我体会到了这两点。不管是做什么吧，多去思考、复盘，同时要利用好自己的暗时间，结果往往总会是不错的。</p>
                  <p>共勉。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-09-13 09:40:22" itemprop="dateCreated datePublished" datetime="2021-09-13T09:40:22+08:00">2021-09-13</time>
                </span>
                <span id="/30032.html" class="post-meta-item leancloud_visitors" data-flag-title="理解了，但写不出来" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>967</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30031.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 个人日记 <i class="label-arrow"></i>
                  </a>
                  <a href="/30031.html" class="post-title-link" itemprop="url">利用好我们的暗时间</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>最近看了一本书叫《暗时间》。一开始我不知道这本书为什么叫这个名字，什么是暗时间啊？</p>
                  <p>翻开这本书才知道，这本书算是作者刘未鹏的个人方法论总结，其中有一个就叫做暗时间，这也是相当重要的一个部分，读完这部分之后我来写写自己的一些感想。</p>
                  <p>首先就说说暗时间吧，暗时间什么意思呢？我们先举几个例子来体会下。</p>
                  <p>比如说一个人，学习看起来非常刻苦，早上不到七点就去自习室了，然后直到晚上熄灯才回来。可是你会发现他考试成绩还是很差。这除了一些智力影响，还有一个重要的影响就是对时间和效率的把控。虽然有的人看起来非常刻苦，但有时候你会发现，他可能人坐在那里，但思绪却已经飞到了九霄云外。有些人学习但时候把一些定义、方法读了又读，但并没有真正地去思考和理解，其实最后还是没有把一件知识想透彻想明白。总的来说，这些有效的时间都没有用来真正去做有效率的事情。</p>
                  <p>比如说一台服务器，配置相当牛逼，不管是内存、CPU、GPU 都是顶配中的顶配，但是却被放在那闲置不用，一点功能也没有发挥出来，这资源就白白浪费掉了。但如果我们把它每天进行一些数据处理、计算，发挥出它的最大价值，这才是这正利用好了这些时间和资源。所以，这台服务器闲置是一天，满载运行计算也是一天，这两种情况，对服务器来说，产生的价值是完全不一样的。</p>
                  <p>每个人每天都有 24 小时，但不同的人，利用这 24 小时的方式不同，那产生的效果也就是不同的。人的一天中，有睡眠时间、通勤时间、工作时间、娱乐时间还有很多碎片时间，在这些时间里面，其实有很多时间是暗时间，有的人利用了这些时间进行了思考和学习，而有的人却在这个时间无所事事。</p>
                  <p>书中特别强调了思考的重要性，一个人在想什么，我们其实是看不出来的，但同时思考又是非常重要的。善于利用暗时间进行思考的人，可以无形中比别人多出好多的时间，从而实际意义上会比别人或好多年。</p>
                  <p>书中有一个比喻我特别喜欢：</p>
                  <blockquote>
                    <p>我们每一个人的生命都像一个沙漏，里面装的沙子都差不多（因为大家的寿命都差不多），但不同的是，有些人的沙漏颈部较细，有些人的沙漏颈部较粗。颈部较细的沙漏可以抓住每一粒时间只沙，虽然沙子总量是一样的，但却会拥有更长的生命。</p>
                  </blockquote>
                  <p>我觉得这个写的是太好了。</p>
                  <p>我们做一件事情，不能单纯地以投入的时间作为评判标准，时间和效率的乘积才是真正有意义的衡量标准。比如说背个英语单词吧，虽然我们一直在朗读，但发现记忆效果就是差，这是因为很多时间我们并没有去投入身心去记忆和思考，去思考这个单词更深层次的用法，和其他单词、场景的联系等等。同样学习一些新的知识，如果我们不去深入思考，也只能浅尝辄止。</p>
                  <p>学习就像电脑的 CPU 处理程序一样，如果我们始终给一个任务分配高的优先级，分配更多的时间到上面，那效果自然就是更好一些。学习知识也是一样，如果我们能够始终多去思考，去思考知识底层更深层的原理和关联，那效果也会更好。</p>
                  <p>但，人的时间总是有限的，比如工作的时间是有限的，学习的时间也是有限的，也有一些时间必须要用来做固定的事情，比如通勤、吃饭等等。但有时候我们就发现，有些人似乎看的东西不我们你多，玩的也不比我们少，但不知道为什么别人就是比我们走的更远。有一个诀窍就是利用了一些暗时间，这部分暗时间完全可以用来思考。</p>
                  <p>比如说走路、买菜、洗漱、通勤、出游、吃饭等等，这些时间都可以看作是暗时间，我们可以充分利用这些时间进行思考，梳理和精细化之前看的和读的东西。慢慢地，时间长了，就会产生巨大的影响。</p>
                  <p>平时生活中，我们可以在大脑中时刻留着几个问题，比如工作上的、生活上的、学习上的都可以，如果记不住的话，那就可以把一些可以利用空闲时间思考的问题记录到一个备忘录里面，有事没事的时候翻出来就思考一下。比如说坐车的时候，我们可以去思考今天遇到的一个算法或设计上的问题。比如说洗漱的时候，我们可以构思一篇文章或者文档的内容和设计。有时候可能洗漱的时候，灵感突然来了，一个问题就马上被想通了。这就是充分利用了暗时间的效果。</p>
                  <p>能把握住暗时间的人，其实就相当于无形中拥有了更多的时间，这些时间被用在了思考之上，也就可以走的更远。</p>
                  <p>好嘞，就先写到这里，大家也可以试试看，让我们把握住自己的时间沙漏，利用好我们的暗时间，相信它会迸发出意想不到的威力的。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-09-12 21:55:22" itemprop="dateCreated datePublished" datetime="2021-09-12T21:55:22+08:00">2021-09-12</time>
                </span>
                <span id="/30031.html" class="post-meta-item leancloud_visitors" data-flag-title="利用好我们的暗时间" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.7k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30030.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30030.html" class="post-title-link" itemprop="url">这么好看的代码分享图是怎么做出来的？</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>有时候我们在逛博客、技术帖子的时候会发现有人是这么分享代码的？</p>
                  <p><img src="https://qiniu.cuiqingcai.com/sizta.png" alt=""></p>
                  <p>这其实是一张图片，虽然说里面的内容不能复制，但是这张图片整体看看起来就很精致有没有？左上角的三个红黄绿的按钮，就是 Mac 中的窗口操作按钮，然后代码的高亮配色都和我们 IDE 中的配色是完全一致的，整体就是一个 Mac 的风格。</p>
                  <p>最近群里也有小伙伴在问这个是怎么做的，这里就来给大家介绍一下。</p>
                  <p>这个工具叫做 carbon，它有自己的网站、代码仓库，另外还有一个类似的VS Code 插件，这里统一给大家介绍下。</p>
                  <h2 id="网站"><a href="#网站" class="headerlink" title="网站"></a>网站</h2>
                  <p>carbon 自己维护了一个网站：<a href="https://carbon.now.sh/" target="_blank" rel="noopener">https://carbon.now.sh/</a>，我们可以打开它来看看：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/s817b.png" alt=""></p>
                  <p>可以看到 carbon 提供了多种选项，比如主题选择、编程语言、还有一些底色、间距的配置，下方就是代码的预览效果，同时我们还可以在这里编辑代码。</p>
                  <p>我们可以在下方任意贴上我们想要贴的代码，比如这里有一段 Python 代码：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">def get_vowels(string):</span><br><span class="line">    <span class="keyword">return</span> [vowel <span class="keyword">for</span> vowel <span class="keyword">in</span> string <span class="keyword">if</span> vowel <span class="keyword">in</span> <span class="string">'aeiou'</span>] </span><br><span class="line"></span><br><span class="line">print(<span class="string">"Vowels are:"</span>, get_vowels(<span class="string">'This is some random string'</span>))</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们可以直接贴进去，然后我们可以选择喜欢的主题配色，语言，同时可以选择背景颜色，还可以点击 setting 的按钮配置更详细的内容：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/mde58.png" alt=""></p>
                  <p>这里的 Window controls 可以控制左上角的现实效果，比如是否带有圆角效果、按钮是否带有颜色，另外还可以控制内边距、阴影等等，还有一些自动调整宽度的配置。</p>
                  <p>完事之后直接点击复制，这里有几个选项，比如复制图片、URL 或者直接复制 iframe。</p>
                  <p>比如点击复制为 iframe 链接就会得到如下内容：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">&lt;iframe</span><br><span class="line">  src=<span class="string">"https://carbon.now.sh/embed?bg=rgba%28255%2C255%2C255%2C1%29&amp;t=material&amp;wt=none&amp;l=python&amp;ds=true&amp;dsyoff=20px&amp;dsblur=68px&amp;wc=true&amp;wa=true&amp;pv=0px&amp;ph=0px&amp;ln=false&amp;fl=1&amp;fm=Hack&amp;fs=14px&amp;lh=133%25&amp;si=false&amp;es=2x&amp;wm=false&amp;code=def%2520get_vowels%28string%29%253A%250A%2520%2520%2520%2520return%2520%255Bvowel%2520for%2520vowel%2520in%2520string%2520if%2520vowel%2520in%2520%27aeiou%27%255D%2520%250A%250Aprint%28%2522Vowels%2520are%253A%2522%252C%2520get_vowels%28%27This%2520is%2520some%2520random%2520string%27%29%29"</span></span><br><span class="line">  style=<span class="string">"width: 561px; height: 146px; border:0; transform: scale(1); overflow:hidden;"</span></span><br><span class="line">  sandbox=<span class="string">"allow-scripts allow-same-origin"</span>&gt;</span><br><span class="line">&lt;<span class="regexp">/iframe&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>复制为 URL 就会直接得到一个可供使用的 URL：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">https:<span class="comment">//carbon.now.sh/?bg=rgba%28255%2C255%2C255%2C1%29&amp;t=material&amp;wt=none&amp;l=python&amp;ds=true&amp;dsyoff=20px&amp;dsblur=68px&amp;wc=true&amp;wa=true&amp;pv=0px&amp;ph=0px&amp;ln=false&amp;fl=1&amp;fm=Hack&amp;fs=14px&amp;lh=133%25&amp;si=false&amp;es=2x&amp;wm=false&amp;code=def%2520get_vowels%28string%29%253A%250A%2520%2520%2520%2520return%2520%255Bvowel%2520for%2520vowel%2520in%2520string%2520if%2520vowel%2520in%2520%27aeiou%27%255D%2520%250A%250Aprint%28%2522Vowels%2520are%253A%2522%252C%2520get_vowels%28%27This%2520is%2520some%2520random%2520string%27%29%29</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>有了 URL 之后我们可以到任意地址引用。</p>
                  <p>当然导出也是，可以选择导出矢量图 svg 还是 png，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/xscsx.png" alt=""></p>
                  <p>我的话一般都是点击复制，然后用我的 ipic 工具上传到 CDN 上面。</p>
                  <h2 id="仓库"><a href="#仓库" class="headerlink" title="仓库"></a>仓库</h2>
                  <p>同时 carbon 还是开源的，GitHub 仓库地址是：<a href="https://github.com/carbon-app/carbon" target="_blank" rel="noopener">https://github.com/carbon-app/carbon</a>，其实这就是刚才我们看到的网站的源码，是基于 Node.js 开发的，扒一扒 package.json源码：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="string">"dependencies"</span>: &#123;</span><br><span class="line">    <span class="string">"@next/bundle-analyzer"</span>: <span class="string">"^10.2.2"</span>,</span><br><span class="line">    <span class="string">"@reach/visually-hidden"</span>: <span class="string">"^0.15.0"</span>,</span><br><span class="line">    <span class="string">"actionsack"</span>: <span class="string">"^0.0.14"</span>,</span><br><span class="line">    <span class="string">"axios"</span>: <span class="string">"^0.21.1"</span>,</span><br><span class="line">    <span class="string">"cm-show-invisibles"</span>: <span class="string">"^3.1.0"</span>,</span><br><span class="line">    <span class="string">"codemirror"</span>: <span class="string">"5.61.1"</span>,</span><br><span class="line">    <span class="string">"codemirror-graphql"</span>: <span class="string">"^1.0.1"</span>,</span><br><span class="line">    <span class="string">"codemirror-mode-elixir"</span>: <span class="string">"^1.1.2"</span>,</span><br><span class="line">    <span class="string">"codemirror-solidity"</span>: <span class="string">"^0.2.3"</span>,</span><br><span class="line">    <span class="string">"date-fns"</span>: <span class="string">"^2.21.3"</span>,</span><br><span class="line">    <span class="string">"dom-to-image"</span>: <span class="string">"^2.6.0"</span>,</span><br><span class="line">    <span class="string">"downshift"</span>: <span class="string">"^6.1.3"</span>,</span><br><span class="line">    <span class="string">"dropperx"</span>: <span class="string">"^1.0.1"</span>,</span><br><span class="line">    <span class="string">"eitherx"</span>: <span class="string">"^1.0.2"</span>,</span><br><span class="line">    <span class="string">"email-validator"</span>: <span class="string">"^2.0.4"</span>,</span><br><span class="line">    <span class="string">"escape-goat"</span>: <span class="string">"^3.0.0"</span>,</span><br><span class="line">    <span class="string">"firebase"</span>: <span class="string">"^8.6.2"</span>,</span><br><span class="line">    <span class="string">"graphql"</span>: <span class="string">"^15.5.0"</span>,</span><br><span class="line">    <span class="string">"highlight.js"</span>: <span class="string">"^10.7.2"</span>,</span><br><span class="line">    <span class="string">"lodash.debounce"</span>: <span class="string">"^4.0.8"</span>,</span><br><span class="line">    <span class="string">"lodash.omitby"</span>: <span class="string">"^4.6.0"</span>,</span><br><span class="line">    <span class="string">"match-sorter"</span>: <span class="string">"^6.3.0"</span>,</span><br><span class="line">    <span class="string">"morphmorph"</span>: <span class="string">"^0.1.3"</span>,</span><br><span class="line">    <span class="string">"ms"</span>: <span class="string">"^2.1.3"</span>,</span><br><span class="line">    <span class="string">"next"</span>: <span class="string">"^10.2.2"</span>,</span><br><span class="line">    <span class="string">"next-offline"</span>: <span class="string">"^5.0.5"</span>,</span><br><span class="line">    <span class="string">"prettier"</span>: <span class="string">"^2.3.0"</span>,</span><br><span class="line">    <span class="string">"react"</span>: <span class="string">"^17.0.2"</span>,</span><br><span class="line">    <span class="string">"react-click-outside"</span>: <span class="string">"^3.0.0"</span>,</span><br><span class="line">    <span class="string">"react-codemirror2"</span>: <span class="string">"^7.2.1"</span>,</span><br><span class="line">    <span class="string">"react-color"</span>: <span class="string">"^2.19.3"</span>,</span><br><span class="line">    <span class="string">"react-dom"</span>: <span class="string">"^17.0.2"</span>,</span><br><span class="line">    <span class="string">"react-image-crop"</span>: <span class="string">"^6.0.16"</span>,</span><br><span class="line">    <span class="string">"react-mailchimp-subscribe"</span>: <span class="string">"^2.1.3"</span>,</span><br><span class="line">    <span class="string">"tohash"</span>: <span class="string">"^1.0.2"</span>,</span><br><span class="line">    <span class="string">"use-climate-change-reminder"</span>: <span class="string">"^0.0.7"</span></span><br><span class="line">  &#125;,</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>可以看到它主要基于 Next、React、CodeMirror 开发的，如果大家想基于此进行二次开发也可以，比如对接云存储，实现一些自动化等等。</p>
                  <p>如果觉得刚才的网站能够满足需求的话，那大可继续使用刚才的网站。</p>
                  <h2 id="VS-Code-插件"><a href="#VS-Code-插件" class="headerlink" title="VS Code 插件"></a>VS Code 插件</h2>
                  <p>另外还有一个类似的 VS Code 插件，也可以实现类似的功能，我觉得还挺好用的，插件叫做 CodeSnap，现在已经十七万多次下载了。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/fj3mz.png" alt=""></p>
                  <p>大家在 VS Code 里面搜索生成就好了。</p>
                  <p>那怎么生成代码图片呢？</p>
                  <p>其实很简单，我们先选中想要分享的代码：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/gsu3i.png" alt=""></p>
                  <p>然后右键菜单选择 CodeSnap 即可，接着在 VS Code 面板就可以生成对应的代码预览效果了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/ehdh5.png" alt=""></p>
                  <p>这时候我们可以点击上方的这个按钮，就可以直接把代码对应的图片下载下来了，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/w42aa.png" alt=""></p>
                  <p>得到的效果就和你自己编辑器里面看到的一样，是不是感觉很不错？</p>
                  <p>CodeSnap 也可以支持在 VSCode 里面更改 settings，目前支持如下内容：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">codesnap.backgroundColor: The background color <span class="keyword">of</span> the snippet<span class="string">'s container. Can be any valid CSS color.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">codesnap.boxShadow: The CSS box-shadow for the snippet. Can be any valid CSS box shadow.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">codesnap.containerPadding: The padding for the snippet'</span>s container. Can be any valid CSS padding.</span><br><span class="line"></span><br><span class="line">codesnap.roundedCorners: <span class="built_in">Boolean</span> value to use rounded corners or square corners <span class="keyword">for</span> the <span class="built_in">window</span>.</span><br><span class="line"></span><br><span class="line">codesnap.showWindowControls: <span class="built_in">Boolean</span> value to show or hide OS X style <span class="built_in">window</span> buttons.</span><br><span class="line"></span><br><span class="line">codesnap.showWindowTitle: <span class="built_in">Boolean</span> value to show or hide <span class="built_in">window</span> title folder_name - file_name.</span><br><span class="line"></span><br><span class="line">codesnap.showLineNumbers: <span class="built_in">Boolean</span> value to show or hide line numbers.</span><br><span class="line"></span><br><span class="line">codesnap.realLineNumbers: <span class="built_in">Boolean</span> value to start <span class="keyword">from</span> the real line number <span class="keyword">of</span> the file instead <span class="keyword">of</span> <span class="number">1.</span></span><br><span class="line"></span><br><span class="line">codesnap.transparentBackground: <span class="built_in">Boolean</span> value to use a transparent background when taking the screenshot.</span><br><span class="line"></span><br><span class="line">codesnap.target: Either container to take the screenshot <span class="keyword">with</span> the container, or <span class="built_in">window</span> to only take the <span class="built_in">window</span>.</span><br><span class="line"></span><br><span class="line">codesnap.shutterAction: Either save to save the screenshot into a file, or copy to copy the screenshot into the clipboard.</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>关于更多的内容大家可以直接到 CodeSnap 插件的主页查看：<a href="https://marketplace.visualstudio.com/items?itemName=adpyke.codesnap" target="_blank" rel="noopener">https://marketplace.visualstudio.com/items?itemName=adpyke.codesnap</a></p>
                  <p>另外这里也顺便提下我的 VS Code 主题，我用的是 Community Material Theme 这个插件：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/dwr6k.png" alt=""></p>
                  <p>然后使用它提供的第一个默认主题：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/r7dax.png" alt=""></p>
                  <p>如果大家觉得不错的话也欢迎试试哈～</p>
                  <p>希望对大家有帮助。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-08-14 22:55:20" itemprop="dateCreated datePublished" datetime="2021-08-14T22:55:20+08:00">2021-08-14</time>
                </span>
                <span id="/30030.html" class="post-meta-item leancloud_visitors" data-flag-title="这么好看的代码分享图是怎么做出来的？" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>4.8k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>4 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30029.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30029.html" class="post-title-link" itemprop="url">邮箱总是被垃圾邮件轰炸？来试试这个临时邮箱生成器吧！</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>有时候我们可能为了测试各种各样的功能，需要用邮箱注册一些网站，然后过段时间就发现这个网站开始往我们的邮箱发送一些垃圾广告信息，比如如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2xjgu.png" alt="image-20210725124859662"></p>
                  <p>很多邮箱服务有自动垃圾邮件分类的功能，但免不了的还是有些不好区分，来了不感兴趣的邮件我们还是要手动设置下规则，有时候关还关不掉。</p>
                  <p>如果我们只是为了简单测试某些功能，同时又不想发生上面的事情，那我们其实可以用一些小号邮箱来注册，或者生成一些临时邮箱来注册。</p>
                  <p>这里来介绍一个工具，帮助快速生成临时邮箱，简单好用。</p>
                  <h2 id="tmpmail"><a href="#tmpmail" class="headerlink" title="tmpmail"></a>tmpmail</h2>
                  <p>这个工具叫做 tmpmail，GitHub 地址是 <a href="https://github.com/sdushantha/tmpmail" target="_blank" rel="noopener">https://github.com/sdushantha/tmpmail</a>，它就是一个简单的命令行 Shell 脚本，安装完了之后就可以使用了，Windows、Linux、Mac 上都是可用的。</p>
                  <p>由于我使用的是 Mac，这里介绍下 Mac 的安装方式，首先安装依赖：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">brew install w3m curl jq</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后根据 GitHub 对应的提示安装即可：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">curl -L <span class="string">"https://git.io/tmpmail"</span> &gt; tmpmail &amp;&amp; chmod +x tmpmail</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>我们也可以把它移动到对应的系统路径下，比如 /usr/bin，/usr/local/bin 等：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">mv tmpmail /usr/<span class="built_in">local</span>/bin/</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样就安装好了，tmpmail 就可以正常使用了。</p>
                  <h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2>
                  <p>使用其实非常简单，首先我们使用 tmpmail 就可以生成一个临时邮箱：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">tmpmail</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果类似如下：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">[ Inbox <span class="keyword">for</span> hl9dvc3wbub@yoggm.com ]</span><br><span class="line"></span><br><span class="line">No new mail</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里其实就是生成了一个临时邮箱，叫做 <a href="mailto:hl9dvc3wbub@yoggm.com">hl9dvc3wbub@yoggm.com</a>，然后下面提示了 No new mail，就是没有新邮件的意思。</p>
                  <p>有朋友就会说了，咋没有密码啊？其实我们无需关心密码的对不对，我们只关心它收到的邮件内容就好了，比如我们应该是拿着这个邮箱去别的网站注册账号，然后网站会往这个邮箱发送一封激活邮件，点击就激活了。所以对于这个临时邮箱，我们只要能知道邮箱里面收到的邮件就好了。</p>
                  <p>所以 tmpmail 其实相当于帮我们维护了密码，我们无需关心，它可以自动帮我们把收件箱里面的邮件列出来。</p>
                  <p>OK，如果我们要更换邮箱也可以，直接重新生成一个就好了：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">tmpmail --generate</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果如下：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">j2uabw3jmfn@wwjmp.com</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这样就重新生成了一个新的邮箱。</p>
                  <p>这时候重新运行 tmpmail，它就会使用当前最新生成的邮箱，运行结果如下：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">[ Inbox <span class="keyword">for</span> j2uabw3jmfn@wwjmp.com ]</span><br><span class="line"></span><br><span class="line">No new mail</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>OK，准备工作就绪。</p>
                  <h2 id="注册测试"><a href="#注册测试" class="headerlink" title="注册测试"></a>注册测试</h2>
                  <p>接下来我们就随便找个网站注册个账号试试吧。</p>
                  <p>比如 Zyte 这个平台，前身叫做 Scrapinghub，提供一些数据爬取的服务，网址是 <a href="https://www.zyte.com/" target="_blank" rel="noopener">https://www.zyte.com/</a>，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/lgo0t.png" alt=""></p>
                  <p>我们来注册下试试：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/z4h21.png" alt=""></p>
                  <p>填上用户名之后，我们使用刚才 tmpmail 生成的临时邮箱来注册这个账号，输入密码之后点击注册。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/ppc5v.png" alt=""></p>
                  <p>这里 Zyte 就提示我们激活邮件就发送出去了，我们需要到对应邮箱里面查收激活链接并激活账号。</p>
                  <h2 id="查收激活"><a href="#查收激活" class="headerlink" title="查收激活"></a>查收激活</h2>
                  <p>OK，回到 tmpmail，看看邮件收到没。</p>
                  <p>还是输入：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">tmpmail</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这时候就可以看到如下运行结果了：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">[ Inbox <span class="keyword">for</span> j2uabw3jmfn@wwjmp.com ]</span><br><span class="line"></span><br><span class="line">231112827   bounce+6ec610.a13e529-j2uabw3jmfn=wwjmp.com@mg.zyte.com   Zyte Email confirmation</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>非常赞，这里就显示了是 <a href="mailto:bounce+6ec610.a13e529-j2uabw3jmfn=wwjmp.com@mg.zyte.com">bounce+6ec610.a13e529-j2uabw3jmfn=wwjmp.com@mg.zyte.com</a> 发送的邮件，邮件标题是 Zyte Email confirmation，然后最前面有个 ID，是 231112827。</p>
                  <blockquote>
                    <p>P.S.：其实看着 Zyte 也是一个临时邮箱发送的这个邮件。</p>
                  </blockquote>
                  <p>那这么打开这个邮件呢？很简单，tmpmail 命令加这个 ID 就好了：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">tmpmail 231112827</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果如下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/l9bdv.png" alt=""></p>
                  <p>这里就把邮件的内容展示出来了，内容就是感谢您的注册，然后点击链接激活即可，tmpmail 还自动解析了可点击的内容，比如超链接变成了可点击的内容，我们可以直接鼠标点击中间蓝色的 <code>Confirm mail address</code> 就在命令行下触发了链接的访问。</p>
                  <p>然后接下来命令行还显示了点击链接之后的网页内容：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/xnred.png" alt=""></p>
                  <p>基本上就是感谢您的注册，您的账户已经成功激活了。</p>
                  <p>完事了！</p>
                  <p>到现在为止我们就轻松利用 tmpmail 利用临时邮箱注册好了一个测试账号。</p>
                  <p>重新回到 Zyte 里面，输入刚才的邮箱和密码就成功登录进来了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/y435j.png" alt=""></p>
                  <p>这里有代理服务、自动内容提取、云爬虫、Splash 渲染服务，大家感兴趣的话也可以试试看～</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-25 10:11:20" itemprop="dateCreated datePublished" datetime="2021-07-25T10:11:20+08:00">2021-07-25</time>
                </span>
                <span id="/30029.html" class="post-meta-item leancloud_visitors" data-flag-title="邮箱总是被垃圾邮件轰炸？来试试这个临时邮箱生成器吧！" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30028.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30028.html" class="post-title-link" itemprop="url">怎样防止同事用 QQ 邮箱提交公司代码？</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>事情是这样的，最近组里新建了一个代码仓库来开发一个新的产品，再加上今天北京下大雨很多同事选择在家工作（包括我也是），于是我就选择用自己的个人电脑来工作。</p>
                  <p>但我的个人电脑里面的 Git 信息是用的我自己的个人邮箱：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">git config --global user.name <span class="string">"Germey"</span></span><br><span class="line">git config --global user.email <span class="string">"cqc@cuiqingcai.com"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这两行命令大家用过 Git 的肯定都敲过对吧？</p>
                  <p>这个配置是全局生效的，所以如果我用 Git 的 commit 命令来提交代码的话，那么 commit 的名字和邮箱就会变成刚才我配置的个人信息。</p>
                  <p>然后如果把代码推送到公司的代码仓库里面，里面就会出现一个奇奇怪怪的用户名和头像，就像这样子：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1626187344425.png" alt=""></p>
                  <p>图中上面两次 commit 就是我用个人电脑提交的，最后的那次 commit 是我上周在公司用公司电脑提交的。</p>
                  <p>这是不是很奇怪？</p>
                  <p>如果其他人也用的个人邮箱提交，那公司代码库里面就会出现各种怪怪的提交人的记录，无从知晓。</p>
                  <p>这肯定不能忍啊，以后要是有谁写了奇怪的代码都不好查是谁写的。</p>
                  <p>于是乎，我灵机一动，想：为何不在提交代码的时候做一个限制呢？</p>
                  <p>能做到吗？当然可以！</p>
                  <h2 id="Git-Hook"><a href="#Git-Hook" class="headerlink" title="Git Hook"></a>Git Hook</h2>
                  <p>这里就介绍一个知识点 - Git Hook，它的意思就是在 Git 各种事件执行前和执行后执行一些自定义的逻辑，比如说，我们定义一个 pre-commit 的 Git Hook，那就能在 commit 之前执行一些操作，我们定义一个 post-push 的 Git Hook，那就能在 push 操作之后执行一些操作。</p>
                  <p>有关具体的内容可以参考官方文档：<a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks" target="_blank" rel="noopener">https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks</a></p>
                  <p>好，那这里我其实就是需要在 commit 之前做一下 Git 信息检查就好了，比如检查配置的邮箱不是工作邮箱，那就不允许执行 commit，所以就不会出现奇奇怪怪的 commit 记录了。</p>
                  <h2 id="实操"><a href="#实操" class="headerlink" title="实操"></a>实操</h2>
                  <p>说干就干。</p>
                  <p>配置 Git Hook 的工具有很多，Git 有原生支持，当然我们也可以用第三方库来做。</p>
                  <p>目前我们的代码仓库是基于 Node.js 开发的，所以 Node.js 的项目配置 Git Hook 比较流行的解决方案就是 husky，所以这里我也用 husky 来做了。</p>
                  <p>首先安装下 husky：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">yarn add husky</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后配置一个 Node.js 的 prepare 命令，这个命令可以在装完包 Node.js 包之后自动执行，所以 prepare 命令就配置成 husky 初始化的脚本，package.json 里面增加如下配置：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">&#123;</span><br><span class="line">  <span class="string">"scripts"</span>: &#123;</span><br><span class="line">    ...</span><br><span class="line">    <span class="string">"prepare"</span>: <span class="string">"npx husky install"</span></span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>OK，这样的话，其他人如果 clone 了这个仓库，装完所有 Node.js 包之后就会自动初始化 husky 的配置，然后在项目本地生成一个 .husky 的初始化目录，这样 Git Hook 就生效了。</p>
                  <p>Git Hook 生效之后，所有定义在 .husky 目录下的 Hook 脚本都会被应用，比如如果在 .husky 目录下添加一个 pre-commit 的脚本，那执行 commit 的之前，该脚本就会被预先执行做一些检查工作。</p>
                  <p>所以 .husky 目录下我就创建了一个 pre-commit 的脚本，写入了如下内容：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">EMAIL=$(git config user.email)</span><br><span class="line"><span class="keyword">if</span> [[ ! <span class="variable">$EMAIL</span> =~ ^[.[:alnum:]]+@microsoft\.com$ ]];</span><br><span class="line"><span class="keyword">then</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">"Your git information is not valid"</span>;</span><br><span class="line">  <span class="built_in">echo</span> <span class="string">"Please run:"</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">'   git config --local user.name "&lt;Your name in Microsoft&gt;"'</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">'   git config --local user.email "&lt;Your alias&gt;@microsoft.com"'</span></span><br><span class="line">  <span class="built_in">exit</span> 1;</span><br><span class="line"><span class="keyword">fi</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这是一个 Linux Shell 脚本，完全遵循 Shell 语法。</p>
                  <p>这里其实就是获取了 <code>git config user.email</code> 的返回结果，然后用正则表达式匹配是否符合公司邮箱格式，比如我们公司邮箱后缀当然是 microsoft.com 后缀，所以这里就用了 <code>^[.[:alnum:]]+@microsoft\.com$</code> 来进行匹配了。这里值得注意的是，为什么这里没有用 <code>\S</code> 来代表非空白字符，而是用了一个 <code>[:alnum]</code> 呢？这是因为 Bash Shell 本身不支持 <code>\S</code> 这种匹配，所以这里得换成 <code>[:alnum]</code>。</p>
                  <p>然后如果不匹配怎么办呢？</p>
                  <p>那就输出一些错误提示就好了，比如这里就提示请使用 <code>git config —-local</code> 命令来配置用户名和邮箱，之所以用<code>-—local</code> 是因为不想该配置影响全局的 Git 配置，所以这个配置只针对该仓库生效，然后 <code>exit 1</code> 就触发异常退出，程序运行终止，从而也不会触发 commit 命令了。</p>
                  <p>有了这个配置，我们来尝试下效果。</p>
                  <p>这会我没有做任何修改，Git 还是原来的配置，即我的全局个人邮箱配置。</p>
                  <p>这时候我执行下 commit 命令，就出现错误提示了：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Your git information is not valid</span><br><span class="line">Please run:</span><br><span class="line">   git config --<span class="built_in">local</span> user.name <span class="string">"&lt;Your name in Microsoft&gt;"</span></span><br><span class="line">   git config --<span class="built_in">local</span> user.email <span class="string">"&lt;alias&gt;@microsoft.com"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>很棒！检测出来了。</p>
                  <p>按照这个提示说的，然后我运行下配置命令：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">git config --global user.name <span class="string">"Qingcai Cui"</span></span><br><span class="line">git config --global user.email <span class="string">"xxxx@microsoft.com"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里呢，我就配置了我的公司个人信息和公司邮箱。</p>
                  <p>然后重新再执行 commit 命令，就不会再出现如上的错误提示了！commit 成功！</p>
                  <p>大功告成！！！</p>
                  <p>有了它，我们就可以成功阻止一些奇奇怪怪的 commit 乱入公司的代码仓库了！</p>
                  <p>然后我把这个 PR 发出去了，有同事似乎也是深有感触，说道：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1626187345161.png" alt=""></p>
                  <p>哈哈哈，有了这个，以后我们应该再也不会看到我们的代码仓库里面有 QQ 邮箱啦！</p>
                  <p>希望对大家有帮助～</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-12 22:55:24" itemprop="dateCreated datePublished" datetime="2021-07-12T22:55:24+08:00">2021-07-12</time>
                </span>
                <span id="/30028.html" class="post-meta-item leancloud_visitors" data-flag-title="怎样防止同事用 QQ 邮箱提交公司代码？" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.6k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30027.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 个人随笔 <i class="label-arrow"></i>
                  </a>
                  <a href="/30027.html" class="post-title-link" itemprop="url">最简单的学习往往是最无效的</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>想必大家都是从学生时代过来的，或者现在还处于学生时代。</p>
                  <p>在学生时代，大家有没有见过，有的同学非常非常努力，上课听得非常认真，笔记也记录得非常认真，同时各种颜色和标记把书上画得密密麻麻，但是似乎考试成绩并没有那么理想。然而有的同学，几乎也不记笔记，书上甚至几乎都是干干净净的，也不见有多么努力，但是考试成绩就是好。</p>
                  <p>这是为什么呢？最近看了《认知天性》这本书的一些内容，觉得说得还是很有道理的，在这里想把我的一些感悟写下来。</p>
                  <h2 id="那些没有效果的努力"><a href="#那些没有效果的努力" class="headerlink" title="那些没有效果的努力"></a>那些没有效果的努力</h2>
                  <p>首先我们不能否认智力上确实有的同学就是聪明，这一点在数理化上体现得更为明显一些。但是在偏重一些记忆的科目上，上述的情况也有很多很多。比如同样记忆一些知识点，背英语单词等，有些同学非常努力地在大声反复背和念，但是效果并不理想，但有的同学其实就简单看几遍，然后后面就记得很牢。</p>
                  <p>说这个例子我想表明的一个观点是：<strong>耗费心血的学习才是深层次的，效果也会更持久，不花力气的学习就像在沙子上写字，今天写上，明天字就消失了。</strong> </p>
                  <p>之前老师经常教导我们，背单词要大声读出来，多读几遍，多拼几遍，手口耳并用。学习一个知识点的时候，我们要反复去看和阅读，并进行一些集中练习。但其实，这些并没有抓住本质，反而可能还是效率最低的学习方式。因为这个单词或知识点，我们只是在大声阅读、拼写而已，这种行为其实可以归为一种不花力气的学习，这个学习过程并没有给大脑带来什么挑战，这种记忆效率往往并不理想，而且就算当时记住了，那也会很快忘记了。</p>
                  <p>其实我之前其实也很多时候也用刚才说的模式来学习。比如背单词的时候我就反复拼好多遍、读好多遍，而很少主动去默写，去联想记忆，去做自测等等。所以，大部分时间，我的其实就是反复机械式地向大脑灌输一些强化的信息，最后的结果就是，很多单词和知识点，我当时从 0 到记忆住一个知识点的过程比较漫长，而且后来绝大多数知识点也都很快忘记了。</p>
                  <h2 id="我印象深刻的知识是怎么来的"><a href="#我印象深刻的知识是怎么来的" class="headerlink" title="我印象深刻的知识是怎么来的"></a>我印象深刻的知识是怎么来的</h2>
                  <p>但我也回想起来，似乎之前学习过的某些知识点我到现在还记得，而且记得很牢。</p>
                  <p>比如我现在就记得几个地理知识点，亚洲和北美洲的分界线是白令海峡，北美洲和南美洲的分界线是巴拿马运河，等等。</p>
                  <p>为什么这几个知识点我记得这么牢呢？因为我当时在记忆这几个知识点的时候，我姐姐正好来了我家，我就让她给我提问这几个知识点。一开始提问的时候我其实并没有记录得多么牢，绞尽脑汁也没想出来，导致好几个问题答错了，错了之后我就去再记一遍，然后又让我姐姐给我提问。似乎经历了三四轮吧，最后我把所有的问题都答对了，于是后来我就对这些知识点的印象深刻很多。</p>
                  <p>正是因为这个过程，我的大脑经历了反复几次有挑战性的任务，在姐姐跟我提问的过程中，大脑触发了一些主动的思考和联想，然后没有记住的知识点再进行更有针对性的记忆。经过反复的几次提问，大脑的思考，知识的检索，这几个知识点就在我脑海中的印象变得更加深刻。</p>
                  <p>所以，耗费心血、对大脑有挑战性的学习才是深层次的，这个过程往往伴随着大脑对信息的主动检索，效果也会更好。</p>
                  <h2 id="什么才是有效的学习"><a href="#什么才是有效的学习" class="headerlink" title="什么才是有效的学习"></a>什么才是有效的学习</h2>
                  <p>所以，在很多情况下，我们要进行一些有效的学习，就需要做一些对大脑有挑战性的事情，这里举几个例子方便大家理解：</p>
                  <ul>
                    <li>
                      <p>比如记忆一个知识点或者背单词的时候，反复阅读的效果往往是很差的，我们可以尝试让自己不看书本复述或默写出来，对大脑带来一些挑战，这样记忆一遍会更加深刻，另外让别人给自己提问或者默写也是不错的强化记忆的有效手段。</p>
                    </li>
                    <li>
                      <p>比如读一本书，我们自以为是看完了，但其实本质上我们只是经历了一次泛读的过程，当时有个印象，但过段时间就几乎忘得差不多了。我们可以尝试拿出一张纸或者打卡一个空的思维导图，让大脑把整体的思维脉络、核心内容梳理出来。这当然是一个非常难的过程，我们可能很难一次性完成，但没关系，想不起来的就把书再打开看看，然后继续默写。多尝试两三次，我们会对整个书本的内容在大脑里面形成更深刻的印象。</p>
                    </li>
                    <li>
                      <p>比如看了一篇讲座或者学习了一个课，最有效的学习和记忆手段往往是把读后感或者总结写出来，或者动手跟着做一遍，因为这个过程伴随着非常多的脉络梳理和大脑主动检索内容的过程。有人说，一个内容只看一遍，最后我们往往只能记住一小部分，但是如果我们能够把整个内容讲出来，那最后我们几乎能记住绝大部分。我也在做类似的尝试，比如今天我看了《认知天性》这本书的第一章内容，我就尝试把自己的读后感写出来，也就是你正看到的这篇文章，我相信我以后会对这部分内容的理解和记忆更加深刻。比如我学习了一个新的知识点，我就尝试把它梳理成自己的一篇文章，在梳理的过程中，我经历了思考、检索、记忆等各个过程，最后理解也会更加全面和深刻。</p>
                    </li>
                  </ul>
                  <p>人天性是懒惰的，学习的过程中，大脑跟着一起懒惰，去机械式地学习往往是不可取的。所以，总的来说，我们在学习的时候不要死板地反复阅读，可以尽量给大脑一些有挑战性的工作，比如尝试默写、复述、思考和梳理等等，让大脑主动去检索和记忆，如果发现想不起来，那我们也知道哪部分内容需要重点学习的内容。只有这样，才是学习和记忆的正确方式。</p>
                  <p>共勉。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-10 02:10:31" itemprop="dateCreated datePublished" datetime="2021-07-10T02:10:31+08:00">2021-07-10</time>
                </span>
                <span id="/30027.html" class="post-meta-item leancloud_visitors" data-flag-title="最简单的学习往往是最无效的" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.1k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30026.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Python <i class="label-arrow"></i>
                  </a>
                  <a href="/30026.html" class="post-title-link" itemprop="url">我又找到了一个破解谷歌验证码的新方案！</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>之前我曾经写过一篇文章说 Google ReCAPTCHA 验证码的绕过方法，当时介绍的是用 2Captcha，然而有些朋友跟我反映说 2Captcha 价格比较贵，而且用起来比较复杂。</p>
                  <p>今天再给大家介绍另一个用于破解 Google ReCAPTCHA 的方法。</p>
                  <h2 id="ReCAPTCHA-介绍"><a href="#ReCAPTCHA-介绍" class="headerlink" title="ReCAPTCHA 介绍"></a>ReCAPTCHA 介绍</h2>
                  <p>可能大家还没听说过什么是 ReCAPTCHA，可能由于某些原因，这个验证码在国内出现不多，不过想必大家应该多多少少见过或用过。它长这个样子：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124428.png" alt=""></p>
                  <p>这时候，只要我们点击最前面的复选框，验证码算法会首先利用其「风险分析引擎」做一次安全检测，如果直接检验通过的话，我们会直接得到如下的结果：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124434.png" alt=""></p>
                  <p>如果算法检测到当前系统存在风险，比如可能是陌生的网络环境，可能是模拟程序，会需要做二次校验。它会进一步弹出类似如下的内容：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124440.png" alt=""></p>
                  <p>比如上面这张图，验证码页面会出现九张图片，同时最上方出现文字「树木」，我们需要点选下方九张图中出现「树木」的图片，点选完成之后，可能还会出现几张新的图片，我们需要再次完成点选，最后点击「验证」按钮即可完成验证。 或者我们可以点击下方的「耳机」图标，这时候会切换到听写模式，验证码会变成这样：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124446.png" alt=""></p>
                  <p>这时候我们如果能填写对验证码读的音频内容，同样可以通过验证。 这两种方式都可以通过验证，验证完成之后，我们才能完成表单的提交，比如完成登录、注册等操作。 这种验证码叫什么名字？ 这个验证码就是 Google 的 ReCAPTCHA V2 验证码，它就属于行为验证码的一种，这些行为包括点选复选框、选择对应图片、语音听写等内容，只有将这些行为校验通过，此验证码才能通过验证。相比于一般的图形验证码来说，此种验证码交互体验更好、安全性会更高、破解难度更大。</p>
                  <p>其实上文所介绍的验证码仅仅是 ReCAPTCHA 验证码的一种形式，是 V2 的显式版本，另外其 V2 版本还有隐式版本，隐式版本在校验的时候不会再显式地出现验证页面，它是通过 JavaScript 将验证码和提交按钮进行绑定，在提交表单的时候会自动完成校验。除了 V2 版本，Google 又推出了最新的 V3 版本，reCAPTCHA V3 验证码会为根据用户的行为来计算一个分数，这个分数代表了用户可能为机器人的概率，最后通过概率来判断校验是否可以通过。其安全性更高、体验更好。 </p>
                  <h2 id="体验"><a href="#体验" class="headerlink" title="体验"></a>体验</h2>
                  <p>那哪里可以体验到 ReCAPTCHA 呢？我们可以打开这个网站：<a href="https://www.google.com/recaptcha/api2/demo" target="_blank" rel="noopener">https://www.google.com/recaptcha/api2/demo</a>，建议科学上网，同时用匿名窗口打开，这样的话测试不会受到历史 Cookies 的干扰，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124451.png" alt=""></p>
                  <p>这时候，我们可以看到下方有个 ReCAPTCHA 的窗口，然后点击之后就出现了一个验证图块。</p>
                  <p>当然靠人工是能解的，但对于爬虫来说肯定不行啊，那怎么自动化解呢？</p>
                  <p>接下来我们就来介绍一个简单好用的平台。</p>
                  <h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2>
                  <p>本次我们介绍的一个 ReCAPTCHA 破解服务叫做 YesCaptcha，主页是 <a href="http://yescaptcha.365world.com.cn/" target="_blank" rel="noopener">http://yescaptcha.365world.com.cn/</a>，它现在同时可以支持 V2 和 V3版本的破解。</p>
                  <p>我们这次就用它来尝试解一下刚才的 ReCAPTCHA 上的 V2 类型验证码：<a href="https://www.google.com/recaptcha/api2/demo" target="_blank" rel="noopener">https://www.google.com/recaptcha/api2/demo</a>。</p>
                  <p>简单注册之后，可以找到首页有一个 Token。我们可以复制下来以备后面使用，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124501.png" alt=""></p>
                  <p>它有两个关键的 API，一个是创建验证码服务任务，另一个是查询任务状态，API 如下：</p>
                  <ul>
                    <li>
                      <p>创建任务：<a href="http://api.yescaptcha.365world.com.cn/v3/recaptcha/create" target="_blank" rel="noopener">http://api.yescaptcha.365world.com.cn/v3/recaptcha/create</a></p>
                    </li>
                    <li>
                      <p>查询状态：<a href="http://api.yescaptcha.365world.com.cn/v3/recaptcha/status" target="_blank" rel="noopener">http://api.yescaptcha.365world.com.cn/v3/recaptcha/status</a></p>
                    </li>
                  </ul>
                  <p>API 文档可以参考这里：<a href="http://docs.yescaptcha.365world.com.cn/" target="_blank" rel="noopener">http://docs.yescaptcha.365world.com.cn/</a></p>
                  <p>经过 API 文档可以看到使用的时候可以配置如下参数：</p>
                  <div class="table-container">
                    <table>
                      <thead>
                        <tr>
                          <th><strong>参数名</strong></th>
                          <th><strong>是否必须</strong></th>
                          <th><strong>说明</strong></th>
                        </tr>
                      </thead>
                      <tbody>
                        <tr>
                          <td>token</td>
                          <td>是</td>
                          <td>请在个人中心获取 (Token)</td>
                        </tr>
                        <tr>
                          <td>siteKey</td>
                          <td>是</td>
                          <td>ReCaptcha SiteKey （固定参数）</td>
                        </tr>
                        <tr>
                          <td>siteReferer</td>
                          <td>是</td>
                          <td>ReCaptcha Referer （一般也为固定参数）</td>
                        </tr>
                        <tr>
                          <td>captchaType</td>
                          <td>否</td>
                          <td>ReCaptchaV2(默认) / ReCaptchaV3</td>
                        </tr>
                        <tr>
                          <td>siteAction</td>
                          <td>否</td>
                          <td>ReCaptchaV3 选填 Action动作 默认verify</td>
                        </tr>
                        <tr>
                          <td>minScore</td>
                          <td>否</td>
                          <td>ReCaptchaV3 选填 最小分数（0.1-0.9）</td>
                        </tr>
                      </tbody>
                    </table>
                  </div>
                  <p>这里就有三个关键信息了：</p>
                  <ul>
                    <li>
                      <p>token：就是刚才我们在 YesCaptcha 上复制下来的参数</p>
                    </li>
                    <li>
                      <p>siteKey：这个是 ReCAPACHA 的标志字符串，稍后我们会演示怎么找。</p>
                    </li>
                    <li>
                      <p>siteReferer，一般是 ReCAPTCHA 的来源网站的 Referer，比如对于当前的案例，该值就是 <a href="https://www.google.com/recaptcha/api2/demo" target="_blank" rel="noopener">https://www.google.com/recaptcha/api2/demo</a></p>
                    </li>
                  </ul>
                  <p>那 siteKey 怎么找呢？其实很简单，我们看下当前 ReCAPTCHA 的 HTML 源码，从源码里面找一下就好了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124514.png" alt=""></p>
                  <p>这里可以看到每个 ReCAPTCHA 都对应一个 div，div 有个属性叫做 date-sitekey，看这里的值就是：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="number">6</span>Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>好，万事俱备了，只差代码了！</p>
                  <h2 id="开工"><a href="#开工" class="headerlink" title="开工"></a>开工</h2>
                  <p>我们就用最简单 requests 来实现下吧，首先把常量定义一下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">TOKEN = <span class="string">'50a07xxxxxxxxxxxxxxxxxxxxxxxxxf78'</span>  <span class="comment"># 请替换成自己的TOKEN</span></span><br><span class="line">REFERER = <span class="string">'https://www.google.com/recaptcha/api2/demo'</span></span><br><span class="line">BASE_URL = <span class="string">'http://api.yescaptcha.365world.com.cn'</span></span><br><span class="line">SITE_KEY = <span class="string">'6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-'</span> <span class="comment"># 请替换成自己的SITE_KEY</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里我们定义了这么几个常量：</p>
                  <ul>
                    <li>
                      <p>TOKEN：就是网站上复制来的 token</p>
                    </li>
                    <li>
                      <p>REFERER：就是 Demo 网站的链接</p>
                    </li>
                    <li>
                      <p>API_BASE_URL：就是 YesCaptcha 的 API 网址</p>
                    </li>
                    <li>
                      <p>SITE_KEY：就是刚才我们找到的 data-sitekey</p>
                    </li>
                  </ul>
                  <p>然后我们定义一个创建任务的方法：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">create_task</span><span class="params">()</span>:</span></span><br><span class="line">    url = <span class="string">f"<span class="subst">&#123;BASE_URL&#125;</span>/v3/recaptcha/create?token=<span class="subst">&#123;TOKEN&#125;</span>&amp;siteKey=<span class="subst">&#123;SITE_KEY&#125;</span>&amp;siteReferer=<span class="subst">&#123;REFERER&#125;</span>"</span></span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        response = requests.get(url)</span><br><span class="line">        <span class="keyword">if</span> response.status_code == <span class="number">200</span>:</span><br><span class="line">            data = response.json()</span><br><span class="line">            print(<span class="string">'response data:'</span>, data)</span><br><span class="line">            <span class="keyword">return</span> data.get(<span class="string">'data'</span>, &#123;&#125;).get(<span class="string">'taskId'</span>)</span><br><span class="line">    <span class="keyword">except</span> requests.RequestException <span class="keyword">as</span> e:</span><br><span class="line">        print(<span class="string">'create task failed'</span>, e)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里就是调 API 来创建任务，没什么好说的。</p>
                  <p>如果创建成功之后会得到一个 task_id，接下来我们就需要用这个 task_id 来轮询查看任务的状态，定义如下的这么一个方法：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">polling_task</span><span class="params">(task_id)</span>:</span></span><br><span class="line">    url = <span class="string">f"<span class="subst">&#123;BASE_URL&#125;</span>/v3/recaptcha/status?token=<span class="subst">&#123;TOKEN&#125;</span>&amp;taskId=<span class="subst">&#123;task_id&#125;</span>"</span></span><br><span class="line">    count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">while</span> count &lt; <span class="number">120</span>:</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            response = requests.get(url)</span><br><span class="line">            <span class="keyword">if</span> response.status_code == <span class="number">200</span>:</span><br><span class="line">                data = response.json()</span><br><span class="line">                print(<span class="string">'polling result'</span>, data)</span><br><span class="line">                status = data.get(<span class="string">'data'</span>, &#123;&#125;).get(<span class="string">'status'</span>)</span><br><span class="line">                print(<span class="string">'status of task'</span>, status)</span><br><span class="line">                <span class="keyword">if</span> status == <span class="string">'Success'</span>:</span><br><span class="line">                    <span class="keyword">return</span> data.get(<span class="string">'data'</span>, &#123;&#125;).get(<span class="string">'response'</span>)</span><br><span class="line">        <span class="keyword">except</span> requests.RequestException <span class="keyword">as</span> e:</span><br><span class="line">            print(<span class="string">'polling task failed'</span>, e)</span><br><span class="line">        <span class="keyword">finally</span>:</span><br><span class="line">            count += <span class="number">1</span></span><br><span class="line">            time.sleep(<span class="number">1</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里就是设置了最长轮询次数 120 次，请求的 API 就是查询任务状态的 API，会得到一个任务状态的结果，如果结果是 Success，那就证明任务成功了，解析其中的 response 结果就是验证码破解之后得到的 token。</p>
                  <p>两个方法调用一下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    task_id = create_task()</span><br><span class="line">    print(<span class="string">'create task successfully'</span>, task_id)</span><br><span class="line">    response = polling_task(task_id)</span><br><span class="line">    print(<span class="string">'get response:'</span>, response[<span class="number">0</span>:<span class="number">40</span>]+<span class="string">'...'</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果类似如下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">response data: &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'taskId'</span>: <span class="string">'1479436991'</span>&#125;&#125;</span><br><span class="line">create task successfully <span class="number">1479436991</span></span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Success'</span>, <span class="string">'response'</span>: <span class="string">'03AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIed5foLb15oWvWVksq9KesDkDd7dgMMr-UmqULZduXTWr87scJXl3djhl2btPO721eFAYsVzSk7ftr4uHBdJWonnEemr9dNaFB9qx5pnxr3P24AC7cCfKlOH_XARaN4pvbPNxx_UY5G5fzKUPFDOV14nNkCWl61jwwC0fuwetH1q99r4hBQxyI6XICD3PiHyHJMZ_-wolcO1R9C90iGQyjzrSMiNqErezO24ODCiKRyX2cVaMwM9plbxDSuyKUVaDHqccz8UrTNNdJ4m2WxKrD9wZDWaSK10Ti1LgsqOWKjKwqBbuyRS_BkSjG6OJdHqJN4bpk_jAcPMO13wXrnHBaXdK4FNDR9-dUvupHEnr7QZEuNoRxwl8FnO2Fgwzp2sJbGeQkMbSVYWdAalE6fzJ8NwsFJxCdDyeyO817buBtvTJ4C06C1uZ92fpPTeYGJwbbicOuqbGfHNTyiSJeRNmt-5RKz0OUiPJOPnmVKGlWBOqwbwCW1WZt-E-hH4FEg4En5TITmmPb_feS9dWKUxudn1U0hHk2vV9PerjZLtI7F67KtgmcqRrARPbwnc6KyAi3Hy1hthP92lv4MRIcO2jx0Llvsja-G2nhjZB0ZoJwkb9106pmqldiwlXxky4Dcg7VPStiCYJvhQpRYol7Iq1_ltU2tyhMqsu_Xa8Z6Mr5ykRCLnmlLb8DV8isndrdwp84wo_vPARGRj7Up9ov-ycb5lDKTf1XRaHiMCa8d2WLy0Pjco9UnsRAPw0FW3MsBJah6ryHUUDho7ffhUUgV1k86ryJym6xbWch1sVC4D5owzrCFn6L-rSLc5SS1pza2zU5LK4kAZCmbXNRffiFrhUY8nP4T1xaR2KMhIaN8HhJQpR8sQh1Azc-QkDy4rwbYmxUrysYGMrAOnmDx9z7tWQXbJE4IgCVMx5wihSiE-T8nbF5y1aJ0Ru9zqg1nZ3GSqsucSnvJA8HV5t9v0QSG5cBC1x5HIceA-2uEGSjwcmYOMw8D_65Dl-d6yVk1YN2FZCgMWY5ewzB1RAFN1BMqKoITQJ64jq3lKATpkc5i7aTA2bRGQyXrbDyMRIrVXKnYMHegfMbDn0l4O81a8vxmevLspKkacVPiqLsAe-73jAxMvsOqaG7cKxMQO9CY3qbtD55YgN0W4p2jyNSVz3aEpffHRqYyWMsRI5LddLgaZQDoHHgGUhV580PSIdZJ5eKd0gOjxIYxKlr0IgbMWRmsG_TgDNImy1c5oey8ojl-zWpOQW7bnfq5Z4tZ10_sCTfoOZVLqRuOsqB1OOO9pLRQojLBP0HUiGhRAr_As9EIDu6F9NIQfdAmCaVvavJbi1CZITFjcywP-tBrHsxpwkCXlwl996MK_XyEDuyWnJVGiVSthUMY306tIh1Xxj93W3KQJCzsfJQcjN-3lGLLeDFddypHyG4yrpRqRHHBNyiNJHgxSk5SaShEhXvByjkepvhrKX3kJssCU04biqqmkrQ49GqBV9OsWIy0nN3OJTx8v05MP8aU8YYkYBF01UbSff4mTfLAhin6iWk84Y074mRbe2MbgFAdU58KnCrwYVxcAR8voZsFxbxNwZXdVeexNx5HlIlSgaAHLWm2kFWmGPPW-ZA7R8Wst-mc7oIKft5iJl8Ea0YFz8oXyVgQk1rd9nDR3xGe5mWL1co0MiW1yvHg'</span>&#125;&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如果其返回的是如上格式的数据，就代表 ReCAPTCHA 验证码已经识别成功了，其返回的 response 字段的内容就是识别的 token，我们直接拿着这个 token 放到表单里面提交就成功了。</p>
                  <p>那这个 token 怎么来用呢？ 其实如果我们用浏览器验证验证成功之后，点击表单提交的时候，在其表单里面会把一个 name 叫做 g-recaptcha-response 的 textarea 赋值，如果验证成功，它的 value 值就是验证之后得到的 token，这个会作为表单提交的一部分发送到服务器进行验证。如果这个字段校验成功了，那就没问题了。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124522.png" alt=""></p>
                  <p>所以，如上的过程相当于为我们模拟了点选验证码的过程，其最终得到的这个 token 其实就是我们应该赋值给 name 为 g-recaptcha-response 的内容。 那么怎么赋值呢？ 很简单，用 JavaScript 就好了。我们可以用 JavaScript 选取到这个 textarea，然后直接赋值即可，代码如下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">document.getElementById(<span class="string">"g-recaptcha-response"</span>).innerHTML=<span class="string">"TOKEN_FROM_YESCAPTCHA"</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>注意这里的 TOKEN_FROM_YESCAPTCHA 需要换成刚才我们所得到的 token 值。我们做爬虫模拟登录的时候，假如是用 Selenium、Puppeteer 等软件，在模拟程序里面，只需要模拟执行这段 JavaScript 代码，就可以成功赋值了。 执行之后，直接提交表单，我们查看下 Network 请求：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124528.png" alt=""></p>
                  <p>可以看到其就是提交了一个表单，其中有一个字段就是 g-recaptcha-response，它会发送到服务端进行校验，校验通过，那就成功了。 所以，如果我们借助于 YesCaptcha 得到了这个 token，然后把它赋值到表单的 textarea 里面，表单就会提交，如果 token 有效，就能成功绕过登录，而不需要我们再去点选验证码了。 最后我们得到如下成功的页面：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2021-07-09-124534.png" alt=""></p>
                  <p>当然我们也可以使用 requests 来模拟完成表单提交：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">verify</span><span class="params">(response)</span>:</span></span><br><span class="line">    url = <span class="string">"https://www.google.com/recaptcha/api2/demo"</span></span><br><span class="line">    data = &#123;<span class="string">"g-recaptcha-response"</span>: response&#125;</span><br><span class="line">    response = requests.post(url, data=data)</span><br><span class="line">    <span class="keyword">if</span> response.status_code == <span class="number">200</span>:</span><br><span class="line">        <span class="keyword">return</span> response.text</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>最后完善一下调用：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    task_id = create_task()</span><br><span class="line">    print(<span class="string">'create task successfully'</span>, task_id)</span><br><span class="line">    response = polling_task(task_id)</span><br><span class="line">    print(<span class="string">'get response:'</span>, response[<span class="number">0</span>:<span class="number">40</span>]+<span class="string">'...'</span>)</span><br><span class="line">    result = verify(response)</span><br><span class="line">    print(result)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果如下：</p>
                  <figure class="highlight">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">response data: &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'taskId'</span>: <span class="string">'1479436991'</span>&#125;&#125;</span><br><span class="line">create task successfully <span class="number">1479436991</span></span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Working'</span>&#125;&#125;</span><br><span class="line">status of task Working</span><br><span class="line">polling result &#123;<span class="string">'status'</span>: <span class="number">0</span>, <span class="string">'msg'</span>: <span class="string">'ok'</span>, <span class="string">'data'</span>: &#123;<span class="string">'status'</span>: <span class="string">'Success'</span>, <span class="string">'response'</span>: <span class="string">'03AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIed5foLb15oWvWVksq9KesDkDd7dgMMr-UmqULZduXTWr87scJXl3djhl2btPO721eFAYsVzSk7ftr4uHBdJWonnEemr9dNaFB9qx5pnxr3P24AC7cCfKlOH_XARaN4pvbPNxx_UY5G5fzKUPFDOV14nNkCWl61jwwC0fuwetH1q99r4hBQxyI6XICD3PiHyHJMZ_-wolcO1R9C90iGQyjzrSMiNqErezO24ODCiKRyX2cVaMwM9plbxDSuyKUVaDHqccz8UrTNNdJ4m2WxKrD9wZDWaSK10Ti1LgsqOWKjKwqBbuyRS_BkSjG6OJdHqJN4bpk_jAcPMO13wXrnHBaXdK4FNDR9-dUvupHEnr7QZEuNoRxwl8FnO2Fgwzp2sJbGeQkMbSVYWdAalE6fzJ8NwsFJxCdDyeyO817buBtvTJ4C06C1uZ92fpPTeYGJwbbicOuqbGfHNTyiSJeRNmt-5RKz0OUiPJOPnmVKGlWBOqwbwCW1WZt-E-hH4FEg4En5TITmmPb_feS9dWKUxudn1U0hHk2vV9PerjZLtI7F67KtgmcqRrARPbwnc6KyAi3Hy1hthP92lv4MRIcO2jx0Llvsja-G2nhjZB0ZoJwkb9106pmqldiwlXxky4Dcg7VPStiCYJvhQpRYol7Iq1_ltU2tyhMqsu_Xa8Z6Mr5ykRCLnmlLb8DV8isndrdwp84wo_vPARGRj7Up9ov-ycb5lDKTf1XRaHiMCa8d2WLy0Pjco9UnsRAPw0FW3MsBJah6ryHUUDho7ffhUUgV1k86ryJym6xbWch1sVC4D5owzrCFn6L-rSLc5SS1pza2zU5LK4kAZCmbXNRffiFrhUY8nP4T1xaR2KMhIaN8HhJQpR8sQh1Azc-QkDy4rwbYmxUrysYGMrAOnmDx9z7tWQXbJE4IgCVMx5wihSiE-T8nbF5y1aJ0Ru9zqg1nZ3GSqsucSnvJA8HV5t9v0QSG5cBC1x5HIceA-2uEGSjwcmYOMw8D_65Dl-d6yVk1YN2FZCgMWY5ewzB1RAFN1BMqKoITQJ64jq3lKATpkc5i7aTA2bRGQyXrbDyMRIrVXKnYMHegfMbDn0l4O81a8vxmevLspKkacVPiqLsAe-73jAxMvsOqaG7cKxMQO9CY3qbtD55YgN0W4p2jyNSVz3aEpffHRqYyWMsRI5LddLgaZQDoHHgGUhV580PSIdZJ5eKd0gOjxIYxKlr0IgbMWRmsG_TgDNImy1c5oey8ojl-zWpOQW7bnfq5Z4tZ10_sCTfoOZVLqRuOsqB1OOO9pLRQojLBP0HUiGhRAr_As9EIDu6F9NIQfdAmCaVvavJbi1CZITFjcywP-tBrHsxpwkCXlwl996MK_XyEDuyWnJVGiVSthUMY306tIh1Xxj93W3KQJCzsfJQcjN-3lGLLeDFddypHyG4yrpRqRHHBNyiNJHgxSk5SaShEhXvByjkepvhrKX3kJssCU04biqqmkrQ49GqBV9OsWIy0nN3OJTx8v05MP8aU8YYkYBF01UbSff4mTfLAhin6iWk84Y074mRbe2MbgFAdU58KnCrwYVxcAR8voZsFxbxNwZXdVeexNx5HlIlSgaAHLWm2kFWmGPPW-ZA7R8Wst-mc7oIKft5iJl8Ea0YFz8oXyVgQk1rd9nDR3xGe5mWL1co0MiW1yvHg'</span>&#125;&#125;</span><br><span class="line">status of task Success</span><br><span class="line">get response: <span class="number">03</span>AGdBq27-ABqvNmgq96iuprN8Mvzfq6_8noknIe...</span><br><span class="line">&lt;!DOCTYPE HTML&gt;&lt;html dir="ltr"&gt;&lt;head&gt;&lt;meta http-equiv="content-type" content="text/html; charset=UTF-8"&gt;&lt;meta name="viewport" content="width=device-width, user-scalable=yes"&gt;&lt;title&gt;ReCAPTCHA demo&lt;/title&gt;&lt;link rel="stylesheet" href="https://www.gstatic.com/recaptcha/releases/TbD3vPFlUWKZD-9L4ZxB0HJI/demo__ltr.css" type="text/css"&gt;&lt;/head&gt;&lt;body&gt;&lt;div class="recaptcha-success"&gt;Verification Success... Hooray!&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>最后就可以发现，模拟提交之后，结果会有一个 <code>Verification Success... Hooray!</code> 的文字，就代表验证成功了！</p>
                  <p>至此，我们就成功完成了 ReCAPTCHA 的破解。</p>
                  <p>上面我们介绍的是 requests 的实现，当然使用 Selenium 等工具也可以实现，具体的 Demo 在文档也写好了，请大家参考文档的说明使用即可。</p>
                  <h2 id="小福利"><a href="#小福利" class="headerlink" title="小福利"></a>小福利</h2>
                  <p>现在 YesCaptcha 的价格我觉得相比之前介绍过的 2Captcha 实惠很多了，它破解一次是花费 10 点数，10 块钱是 10000 点数，所以平均破解一次验证码一分钱，新用户是送 1000 点数，可以破解 100 次。我个人觉得很实惠了。</p>
                  <p>大家有需要的话可以试试看！</p>
                  <p>溜了溜了～</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-09 21:31:11" itemprop="dateCreated datePublished" datetime="2021-07-09T21:31:11+08:00">2021-07-09</time>
                </span>
                <span id="/30026.html" class="post-meta-item leancloud_visitors" data-flag-title="我又找到了一个破解谷歌验证码的新方案！" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>10k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>10 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30025.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30025.html" class="post-title-link" itemprop="url">GitHub 新出的功能！可以帮我们自动写代码</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>今天逛 GitHub 的时候发现了 GitHub 出了一个新的 Feature，叫做 GitHub Copilot，说可以帮我们自动写代码！</p>
                  <p>网址是这个：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/zp24u.png" alt=""></p>
                  <p>点进来之后就几个醒目的大字 - Your AI pair programmer，你的人工智能编程伙伴。</p>
                  <p>这里有几个示例是这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/k1juq.png" alt=""></p>
                  <p>怎么个人工智能法呢？</p>
                  <p>这里前 7 行都是人写的，后面的 17 行都是人工智能帮写的。</p>
                  <p>我们需要写啥呢？我们来详细看看这个例子。</p>
                  <p>首先创建了一个 sentiment.ts 文件，然后引入了一个 Node.js 的包叫做 fetch-h2，然后写了两行注释：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="comment">// Determine whether the sentiment of text is positive</span></span><br><span class="line"><span class="comment">// Use a web service</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>什么意思呢？就是用注释写了我要写个啥东西，翻译过来如下：</p>
                  <ul>
                    <li>
                      <p>判断一句话的包含的情感是正面的还是负面的。（比如说“我好开心”就包含了积极情绪，句子包含的情感就是正面的；比如“你太坏了”就包含了负面评价，句子的情感就是负面的。）</p>
                    </li>
                    <li>
                      <p>使用 Web 服务来实现。</p>
                    </li>
                  </ul>
                  <p>然后定义了一个方法的声明：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">isPositive</span>(<span class="params">text: string</span>): <span class="title">Promise</span>&lt;<span class="title">boolean</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>没了。</p>
                  <p>就导入了一个包，然后写了两句注释，定义了一个方法的参数和返回值，人做的事就这么多。</p>
                  <p>然后 GitHub Copilot 就能帮我们把代码写出来，它写的内容如下：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">  <span class="keyword">const</span> response = <span class="keyword">await</span> fetch(<span class="string">`http://text-processing.com/api/sentiment/`</span>, &#123;</span><br><span class="line">    method: <span class="string">"POST"</span>,</span><br><span class="line">    body: <span class="string">`text=<span class="subst">$&#123;text&#125;</span>`</span>,</span><br><span class="line">    headers: &#123;</span><br><span class="line">      <span class="string">"Content-Type"</span>: <span class="string">"application/x-www-form-urlencoded"</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">const</span> json = <span class="keyword">await</span> response.json();</span><br><span class="line">  <span class="keyword">return</span> json.label === <span class="string">"pos"</span>;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>没错，它智能分析了我们人写的注释和方法的声明，然后就把代码写出来了。</p>
                  <p>这里就调用了一个 API，然后还自动构造了 POST 请求，获取返回结果，然后比对返回结果的 label 是不是 pos，如果是，那就代表句子包含了积极程序，返回 false 就不是积极情绪。</p>
                  <p>虽然说规范程度上一般，没有异常处理什么的，但是已经相当了不起了有没有！</p>
                  <ul>
                    <li>
                      <p>它居然能准确理解注释中我们描述的两个需求</p>
                    </li>
                    <li>
                      <p>它居然知道调用哪个 API 来判断文本的情感信息</p>
                    </li>
                    <li>
                      <p>它居然还能没有语法错误地把一个 JavaScript 方法写出来</p>
                    </li>
                  </ul>
                  <p>牛逼了！</p>
                  <p>当然它不止能写 JavaScript，还能写很多其他的语言，我们再来看一个 Python的 例子。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/9w45q.png" alt=""></p>
                  <p>这里我们新建了一个 parse_expenses 的 Python 文件，然后定义了一个 parse_expenses 方法，接收一个参数叫做 expenses_string，然后写明注释如下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="string">"""</span></span><br><span class="line"><span class="string">Parse the list of expenses and return the list of triples (date, value, currency).</span></span><br><span class="line"><span class="string">Ignore lines starting with #.</span></span><br><span class="line"><span class="string">Parse the date using datetime.</span></span><br><span class="line"><span class="string">Example expenses_string:</span></span><br><span class="line"><span class="string">      2016-01-02 -34.01 USD</span></span><br><span class="line"><span class="string">      2016-01-03 2.59 DKK</span></span><br><span class="line"><span class="string">      2016-01-03 -2.72 EUR</span></span><br><span class="line"><span class="string">"""</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里就写了，解析下面三行消费数据，然后返回日期、数值、单位，同时要求忽略掉开头是 # 的行，时间要用 datetime 库来解析出来。</p>
                  <p>然后 AI 就帮我们写了如下代码：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">expenses = []</span><br><span class="line"><span class="keyword">for</span> line <span class="keyword">in</span> expenses_string.splitlines():</span><br><span class="line">    <span class="keyword">if</span> line.startswith(<span class="string">"#"</span>):</span><br><span class="line">        <span class="keyword">continue</span></span><br><span class="line">    date, value, currency = line.split(<span class="string">" "</span>)</span><br><span class="line">    expenses.append((datetime.datetime.strptime(date, <span class="string">"%Y-%m-%d"</span>),</span><br><span class="line">                     float(value),</span><br><span class="line">                     currency))</span><br><span class="line"><span class="keyword">return</span> expenses</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>看完这个我惊呆了，它全都做到了！</p>
                  <ul>
                    <li>
                      <p>跟它说了忽略开头是 # 的行，它就添加了一个判断</p>
                    </li>
                    <li>
                      <p>而且它智能分析了下面的三行数据是什么格式的，然后还知道用空格把它分开</p>
                    </li>
                    <li>
                      <p>分开之后，针对日期，他还知道用 datetime 解析一下，而且还知道是什么格式，年月日中间用的是横线</p>
                    </li>
                    <li>
                      <p>数值还自动转成了 float 类型</p>
                    </li>
                    <li>
                      <p>最后组成了一个元组返回了</p>
                    </li>
                  </ul>
                  <p>简直，我简直不相信这是 AI 写的，感觉这个作为面试题，人也不一定一次性完整写得很好，AI 全都做到了！</p>
                  <p>这。</p>
                  <p>当然除了 JavaScript、Python，它还会很多语言，比如 Go、Ruby、TypeScript 都会。</p>
                  <p>这是背后究竟是什么技术呢？</p>
                  <p>看了看官网的介绍，说是基于 OpenAI 做的，官方原话如下：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Trained on billions of lines of public code, GitHub Copilot puts the knowledge you need at your fingertips, saving you time and helping you stay focused.</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>翻译过来就是：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">GitHub Copilot 接受了数十亿行公共代码的训练，让您所需的知识触手可及，从而节省您的时间并帮助您保持专注。</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>反正就是他们训练了一个模型，这个模型接受了数十亿行代码作为训练输入，最后就学会了人怎么写代码了。</p>
                  <p>这波可以。</p>
                  <p>然后官方还介绍说：</p>
                  <p>GitHub Copilot 尤其擅长写 Python、Go、Ruby、JavaScript、TypeScript，并且现在已经发布成了 VS Code 中的一个插件。在我们写 Code 的时候，这个插件就会跟 OpenAI 的模型通信，然后目前看到的内容帮助我们自动写出想要的代码，基本流程如下图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/5nlkk.png" alt=""></p>
                  <p>好家伙，那我赶紧来下载看看。</p>
                  <p>到 VS Code 里面搜索下 Copilot，果然有，已经十万多下载量了。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/mlztv.png" alt=""></p>
                  <p>装上之后，它让我登录 GitHub 授权，登录之后，它弹了一个令人悲伤的信息：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/m1jef.png" alt=""></p>
                  <p>它说我现在还没有权限使用，请访问 <a href="https://copilot.github.com" target="_blank" rel="noopener">https://copilot.github.com</a> 申请假如白名单。</p>
                  <p>也就是还没完全开放使用，需要申请才能用。</p>
                  <p>于是乎，我就去申请了下，点下网站的 Sign Up 即可，现在我已经在等待名单中了，等通过了我应该就能用了，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/q3el1.png" alt=""></p>
                  <p>大家感兴趣的话也赶紧去申请试试吧！</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-07 23:31:21" itemprop="dateCreated datePublished" datetime="2021-07-07T23:31:21+08:00">2021-07-07</time>
                </span>
                <span id="/30025.html" class="post-meta-item leancloud_visitors" data-flag-title="GitHub 新出的功能！可以帮我们自动写代码" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>2.7k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>2 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30024.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30024.html" class="post-title-link" itemprop="url">一个相当有意思的字符问题</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>最近在实现一个功能，那就是显示图片的分辨率信息。</p>
                  <p>由于分辨率无非就是宽乘以高的格式嘛，比如 250x140 这样的。</p>
                  <p>然后我代码里面就实现成了这样子：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;dimension?.width&#125;</span>x<span class="subst">$&#123;dimension?.height&#125;</span>`</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>dimension 就是分辨率对象，它有宽高两个信息。</p>
                  <p>然而，一位大佬给我 Review 代码的时候发现了这个问题，他说你看看其他地方是怎么表示的，需不需要不同地区做 Localization（国际化 i18n 处理）？</p>
                  <p>于是我就找了下 Chrome 浏览器怎么显示的，随便打开了一张图片：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/nw4me.png" alt=""></p>
                  <p>这不就是这么显示的吗？</p>
                  <p>我写的没错啊？到底问题出在了哪里？</p>
                  <p>不解之时又去求助大佬，大佬说：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Is Chrome using the letter x or are they using the × character?</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p><img src="https://qiniu.cuiqingcai.com/u31yu.png" alt=""></p>
                  <p>我恍然大悟，原来是字符问题！</p>
                  <p>然后我就追踪了下 Chrome 这页的代码：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/hepup.png" alt=""></p>
                  <p>由于这个信息是在选项卡显示的，那么一定在 title 节点里面，我把这个字符复制了出来，跟字母 x 对比了下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/01zxn.png" alt=""></p>
                  <p>果然不是字母 x，而是字符 ×，有趣！</p>
                  <p>后来我改成了 × 就好了，修改如下：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">return</span> <span class="string">`<span class="subst">$&#123;dimension?.width&#125;</span>×<span class="subst">$&#123;dimension?.height&#125;</span>`</span>;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>然后告诉了大佬，大佬欣慰地笑了，说：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Nice, no localization necessary =)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p><img src="https://qiniu.cuiqingcai.com/hwaj2.png" alt=""></p>
                  <p>妙极了！</p>
                  <p>哈哈，这里就简单记录下，非常有意思，不然我还一直以为是一个字母 x 呢。</p>
                  <p>以后大家表示分辨率的时候，更标准的形式应该是用字符 × 而不是字母 x，比如应该是：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="number">250</span>×<span class="number">160</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>而不是：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="number">250</span>x160</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>涨姿势了！</p>
                  <blockquote>
                    <p>彩蛋：我的微信昵称其实也有类似的字符，比如「崔庆才丨静觅」中间的「丨」是一个汉字（发音为 gun），而不是竖线「|」，哈哈哈。</p>
                  </blockquote>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-03 15:42:06" itemprop="dateCreated datePublished" datetime="2021-07-03T15:42:06+08:00">2021-07-03</time>
                </span>
                <span id="/30024.html" class="post-meta-item leancloud_visitors" data-flag-title="一个相当有意思的字符问题" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>807</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30023.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30023.html" class="post-title-link" itemprop="url">爽爆了！我搞了一个网页版 VS Code</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>VS Code 想必大家都听说过吧，VS Code 凭借其强大的插件生态简直把 IDE 玩出花来了，现在我身边越来越多的程序员朋友现在都转向使用 VS Code 来写代码了，我也不例外。</p>
                  <p>但大家知道 VS Code 本身是用什么写的吗？没错，其实是 JavaScript 写的，准确来说是用 TypeScript 写的。</p>
                  <p>这时候我就想问，既然是用 TypeScript 写的，那它有没有网页版呢？</p>
                  <p>有人就要问了，网页版的 VS Code 有啥用啊，其实它能解决很多痛点：</p>
                  <ul>
                    <li>
                      <p>如果我能在网页版的 VS Code 里面写代码，这样换了一个 PC 之后我只需要打卡这个网页就能接着写了，多么简单方便。</p>
                    </li>
                    <li>
                      <p>另外我写了代码，想给别人复现现场看效果，直接甩给他一个网页链接就好了。</p>
                    </li>
                    <li>
                      <p>别人遇到问题想让我帮调试，那他在里面写完了，然后直接给我链接就好了。</p>
                    </li>
                  </ul>
                  <p>舒服吧！</p>
                  <p>那就来整一个吧！</p>
                  <p>于是我就找官网的支持，但是没找到官网有说 VS Code 网页版的任何事情。</p>
                  <p>但是找到了一个开源项目，叫做 code-server，运行之后就可以在浏览器里面打卡 VS Code 了，GitHub 地址是：<a href="https://github.com/cdr/code-server" target="_blank" rel="noopener">https://github.com/cdr/code-server</a>。</p>
                  <p>它的官方介绍是：</p>
                  <blockquote>
                    <p>Run <a href="https://github.com/Microsoft/vscode" target="_blank" rel="noopener">VS Code</a> on any machine anywhere and access it in the browser.</p>
                  </blockquote>
                  <p>正式我想要的！它在浏览器里面的运行效果如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/titx7.png" alt=""></p>
                  <h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2>
                  <p>接下来那就安装试试吧，它支持多个平台，只需要运行一条命令就能安装了：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">curl -fsSL https://code-server.dev/install.sh | sh</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这条命令运行之后会自动判断当前的平台，然后运行安装步骤。</p>
                  <p>安装完了之后会有一个可用的 code-server 命令，运行之后便可以在本地启动 code-server 服务了，然后就可以在浏览器中打开 VS Code 了，就像上图所示。</p>
                  <h2 id="Docker"><a href="#Docker" class="headerlink" title="Docker"></a>Docker</h2>
                  <p>但这 code-server 仅仅是在本地运行起来了。</p>
                  <p>如果我想将其部署到公网供我随时访问呢？或者极端一点，如果我想为其他人也部署一个 code-server 怎么办呢？或者我想为一百个人部署自己专属的 code-server 怎么办呢？</p>
                  <p>所以，这时候一个很好的方案就是上 Docker + Kubernetes 了。</p>
                  <p>既然要上 Docker，那就顺便对 code-server 做一些基础化的配置吧，比如预装一些插件，比如设置一些主题，比如设置一些编辑器配置等等。</p>
                  <p>我本地的 VS Code 现在在用一个我个人觉得比较好看的主题，叫做 Material Ocean，效果是这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/zb48p.png" alt=""></p>
                  <p>这是通过安装一个插件实现的，叫做 Material Theme：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/2wfbt.png" alt=""></p>
                  <p>另外还有一些基础的插件，比如 Python的支持、自动提示等等。</p>
                  <p>另外既然要支持 Python 了，那也可以在 Docker 里面配置一些基础的 Python 库，以免使用的时候再安装。</p>
                  <p>其他的一些配置比如代码规范、缩进、换行等都可以通过 VS Code 的一些 settings.json 配置来实现。</p>
                  <p>等等还有一些其他的优化项可以自行发挥啦。</p>
                  <p>基本上就是这么多了，所以接下来就可以写 Dockerfile 了。</p>
                  <p>这里我直接基于 ubuntu 18.04 来开始搭建了，编写一个 Dockerfile 如下：</p>
                  <figure class="highlight docker">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">FROM</span> ubuntu:<span class="number">18.04</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> apt-get update &amp;&amp; apt-get install -y \</span></span><br><span class="line"><span class="bash">    openssl \</span></span><br><span class="line"><span class="bash">    net-tools \</span></span><br><span class="line"><span class="bash">    git \</span></span><br><span class="line"><span class="bash">    zsh \</span></span><br><span class="line"><span class="bash">    locales \</span></span><br><span class="line"><span class="bash">    sudo \</span></span><br><span class="line"><span class="bash">    dumb-init \</span></span><br><span class="line"><span class="bash">    vim \</span></span><br><span class="line"><span class="bash">    curl \</span></span><br><span class="line"><span class="bash">    wget \</span></span><br><span class="line"><span class="bash">    bash-completion \</span></span><br><span class="line"><span class="bash">    python3 \</span></span><br><span class="line"><span class="bash">    python3-pip \</span></span><br><span class="line"><span class="bash">    python3-setuptools \</span></span><br><span class="line"><span class="bash">    build-essential \</span></span><br><span class="line"><span class="bash">    python3-dev \</span></span><br><span class="line"><span class="bash">    libssl-dev \</span></span><br><span class="line"><span class="bash">    libffi-dev \</span></span><br><span class="line"><span class="bash">    libxml2 \</span></span><br><span class="line"><span class="bash">    libxml2-dev \</span></span><br><span class="line"><span class="bash">    libxslt1-dev \</span></span><br><span class="line"><span class="bash">    zlib1g-dev</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> chsh -s /bin/bash</span></span><br><span class="line"><span class="keyword">ENV</span> <span class="keyword">SHELL</span><span class="bash">=/bin/bash</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> ARCH=amd64 &amp;&amp; \</span></span><br><span class="line"><span class="bash">    curl -sSL <span class="string">"https://github.com/boxboat/fixuid/releases/download/v0.4.1/fixuid-0.4.1-linux-<span class="variable">$ARCH</span>.tar.gz"</span> | tar -C /usr/<span class="built_in">local</span>/bin -xzf - &amp;&amp; \</span></span><br><span class="line"><span class="bash">    chown root:root /usr/<span class="built_in">local</span>/bin/fixuid &amp;&amp; \</span></span><br><span class="line"><span class="bash">    chmod 4755 /usr/<span class="built_in">local</span>/bin/fixuid &amp;&amp; \</span></span><br><span class="line"><span class="bash">    mkdir -p /etc/fixuid &amp;&amp; \</span></span><br><span class="line"><span class="bash">    <span class="built_in">printf</span> <span class="string">"user: coder\ngroup: coder\n"</span> &gt; /etc/fixuid/config.yml</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> CODE_SERVER_VERSION=3.10.2 &amp;&amp; \</span></span><br><span class="line"><span class="bash">    curl -sSOL https://github.com/cdr/code-server/releases/download/v<span class="variable">$&#123;CODE_SERVER_VERSION&#125;</span>/code-server_<span class="variable">$&#123;CODE_SERVER_VERSION&#125;</span>_amd64.deb &amp;&amp; \</span></span><br><span class="line"><span class="bash">    sudo dpkg -i code-server_<span class="variable">$&#123;CODE_SERVER_VERSION&#125;</span>_amd64.deb</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> locale-gen en_US.UTF-8</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENV</span> LC_ALL=en_US.UTF-<span class="number">8</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> adduser --disabled-password --gecos <span class="string">''</span> coder &amp;&amp; \</span></span><br><span class="line"><span class="bash">    adduser coder sudo &amp;&amp; \</span></span><br><span class="line"><span class="bash">    <span class="built_in">echo</span> <span class="string">'%sudo ALL=(ALL) NOPASSWD:ALL'</span> &gt;&gt; /etc/sudoers;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> chmod g+rw /home &amp;&amp; \</span></span><br><span class="line"><span class="bash">    mkdir -p /home/coder/workspace &amp;&amp; \</span></span><br><span class="line"><span class="bash">    mkdir -p /home/coder/.<span class="built_in">local</span> &amp;&amp; \</span></span><br><span class="line"><span class="bash">    chown -R coder:coder /home/coder &amp;&amp; \</span></span><br><span class="line"><span class="bash">    chown -R coder:coder /home/coder/.<span class="built_in">local</span> &amp;&amp; \</span></span><br><span class="line"><span class="bash">    chown -R coder:coder /home/coder/workspace;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">USER</span> coder</span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> git <span class="built_in">clone</span> --depth 1 https://github.com/junegunn/fzf.git ~/.fzf &amp;&amp; \</span></span><br><span class="line"><span class="bash">        ~/.fzf/install</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENV</span> PASSWORD=$&#123;PASSWORD:-P@ssw0rd&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> ./extensions /home/coder/.<span class="built_in">local</span>/extensions</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> /usr/bin/code-server --install-extension ms-python.python &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension esbenp.prettier-vscode &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension equinusocio.vsc-material-theme &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension codezombiech.gitignore &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension piotrpalarz.vscode-gitignore-generator &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension aeschli.vscode-css-formatter &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension donjayamanne.githistory &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension ecmel.vscode-html-css &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension pkief.material-icon-theme &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension equinusocio.vsc-material-theme-icons &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension eg2.vscode-npm-script &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension ms-ceintl.vscode-language-pack-zh-hans &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension /home/coder/.<span class="built_in">local</span>/extensions/tkrkt.linenote-1.2.1.vsix &amp;&amp; \</span></span><br><span class="line"><span class="bash">    /usr/bin/code-server --install-extension dbaeumer.vscode-eslint</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> /usr/bin/python3 -m pip install -U pip setuptools</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> /usr/bin/python3 -m pip install requests httpx scrapy aiohttp pyquery beautifulsoup4 \</span></span><br><span class="line"><span class="bash">  selenium pyppeteer pylint flask django tornado numpy pandas scipy autopep8</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> settings.json /home/coder/.<span class="built_in">local</span>/share/code-server/User/settings.json</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> sudo chown coder /home/coder/.<span class="built_in">local</span>/share/code-server/User/settings.json</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> entrypoint.sh /home/coder/.<span class="built_in">local</span>/entrypoint.sh</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> sudo chmod +x /home/coder/.<span class="built_in">local</span>/entrypoint.sh</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">WORKDIR</span><span class="bash"> /home/coder/workspace</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">8080</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ENTRYPOINT</span><span class="bash"> [<span class="string">"/bin/sh"</span>, <span class="string">"/home/coder/.local/entrypoint.sh"</span>]</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里就直接把 Dockerfile 列出来了，主要分这么几步：</p>
                  <ul>
                    <li>
                      <p>装一些基本的环境依赖库</p>
                    </li>
                    <li>
                      <p>设置 shell </p>
                    </li>
                    <li>
                      <p>安装 code-server</p>
                    </li>
                    <li>
                      <p>设置工作目录</p>
                    </li>
                    <li>
                      <p>安装 code-server 插件</p>
                    </li>
                    <li>
                      <p>安装 Python 常用的库</p>
                    </li>
                    <li>
                      <p>设置 VS Code 的 settings</p>
                    </li>
                    <li>
                      <p>设置运行目录</p>
                    </li>
                    <li>
                      <p>设置运行脚本入口</p>
                    </li>
                  </ul>
                  <p>比如 VS Code 插件我就提前装好了 Material Theme 插件，然后在 settings.json 里面启用对应的主题即可：</p>
                  <figure class="highlight json">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">"workbench.colorTheme"</span>: <span class="string">"Material Theme"</span>,</span><br><span class="line">  <span class="attr">"workbench.iconTheme"</span>: <span class="string">"material-icon-theme"</span>,</span><br><span class="line">  <span class="attr">"git.enableSmartCommit"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">"editor.tabSize"</span>: <span class="number">2</span>,</span><br><span class="line">  <span class="attr">"editor.detectIndentation"</span>: <span class="literal">false</span>,</span><br><span class="line">  <span class="attr">"editor.formatOnSave"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">"editor.formatOnPaste"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">"editor.defaultFormatter"</span>: <span class="string">"esbenp.prettier-vscode"</span>,</span><br><span class="line">  <span class="attr">"editor.fontSize"</span>: <span class="number">16</span>,</span><br><span class="line">  <span class="attr">"editor.suggestSelection"</span>: <span class="string">"first"</span>,</span><br><span class="line">  <span class="attr">"files.autoGuessEncoding"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">"files.autoSave"</span>: <span class="string">"afterDelay"</span>,</span><br><span class="line">  <span class="attr">"terminal.integrated.inheritEnv"</span>: <span class="literal">false</span>,</span><br><span class="line">  <span class="attr">"vetur.experimental.templateInterpolationService"</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">"[typescript]"</span>: &#123;</span><br><span class="line">    <span class="attr">"editor.tabSize"</span>: <span class="number">2</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">"[javascript]"</span>: &#123;</span><br><span class="line">    <span class="attr">"editor.tabSize"</span>: <span class="number">2</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">"[python]"</span>: &#123;</span><br><span class="line">    <span class="attr">"editor.tabSize"</span>: <span class="number">4</span>,</span><br><span class="line">    <span class="attr">"editor.defaultFormatter"</span>: <span class="string">"ms-python.python"</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里配置文件主要配置了主题、字体大小、缩进等内容，当然这个如果你要自己配置的话就按照自己的喜好来就好了。</p>
                  <p>最后通过 docker-compose.json 文件配置镜像信息：</p>
                  <figure class="highlight yaml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="attr">version:</span> <span class="string">"3"</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">code-server:</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">"code-server"</span></span><br><span class="line">    <span class="attr">build:</span> <span class="string">.</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">"germey/code-server"</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">"8080:8080"</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>OK，基本就是这样，运行：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">docker-compose build</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>就可以成功构建一个镜像了，然后运行：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">docker-compose push</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>即可把镜像 push 到我的 Docker Hub 上面，等待部署即可。</p>
                  <h2 id="Kubernetes-部署"><a href="#Kubernetes-部署" class="headerlink" title="Kubernetes 部署"></a>Kubernetes 部署</h2>
                  <p>对于部署 Kubernetes 来说，如果要做到方便部署且灵活管理的话，那就不得不用到 Helm 了，我可以写一个 Helm Chart，定义好一些模板文件和占位符，同时设置默认的配置选项，这样我们就可以通过一条简单的命令来部署这个 Docker 镜像了。</p>
                  <blockquote>
                    <p>如果你没有用过 Helm 的话可以搜索相关资料了解下。</p>
                  </blockquote>
                  <p>这里 Chart 的具体实现我就不再赘述了，主要就包括了几个部分：</p>
                  <ul>
                    <li>
                      <p>Deployment</p>
                    </li>
                    <li>
                      <p>Service</p>
                    </li>
                    <li>
                      <p>Ingress</p>
                    </li>
                    <li>
                      <p>PersistentVolumeClaim</p>
                    </li>
                    <li>
                      <p>ServiceAccount</p>
                    </li>
                    <li>
                      <p>Secret</p>
                    </li>
                  </ul>
                  <p>具体的配置我都放在 GitHub 了：<a href="https://github.com/Python3WebSpider/CodeServer/tree/master/chart" target="_blank" rel="noopener">https://github.com/Python3WebSpider/CodeServer/tree/master/chart</a>，需要的话自取即可。</p>
                  <p>有了 Chart 之后，我只需要一条命令即可部署一个在线的 VS Code，命令如下：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">helm install code-server-&lt;username&gt; . --namespace &lt;namespace&gt; --<span class="built_in">set</span> user=&lt;username&gt; --<span class="built_in">set</span> password=&lt;password&gt;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <blockquote>
                    <p>注意运行目录在 chart 路径下才可以。</p>
                  </blockquote>
                  <p>这里我们传入了 usrname、namespace、password。</p>
                  <p>这里我配置了解析域名 code-<username>.scrape.center，比如我要配置一个 code-germey.scrape.center，密码是 1234，那就只需要运行该命令即可：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">helm install code-server-germey . --namespace scrape --<span class="built_in">set</span> user=germey --<span class="built_in">set</span> password=1234</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里用户名我替换成了 germey，命名空间我用了 scrape，密码用了 1234。</p>
                  <p>运行这条命令之后，我就能得到一个 <a href="https://code-germey.scrape.center/" target="_blank" rel="noopener">https://code-germey.scrape.center/</a> 网站了。</p>
                  <p>没错，就是一条命令部署一个 VS Code，而且有专属域名。</p>
                  <p>打开之后效果如下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/9yyit.png" alt=""></p>
                  <p>输入对应的密码之后，就可以进入对应的 VS Code 编辑器页面了，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/0rqpo.png" alt=""></p>
                  <p>这里我可以新建 Python 文件，然后在线运行：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/g4wt3.png" alt=""></p>
                  <p>另外还可以在命令行下像在 Linux 下一样操作，比如安装一个新的 Python 库：</p>
                  <figure class="highlight bash">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">pip3 install pillow</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p><img src="https://qiniu.cuiqingcai.com/5uycp.png" alt=""></p>
                  <p>非常方便。</p>
                  <p>另外插件页面也可以看到我安装的一些插件：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/3hvgd.png" alt=""></p>
                  <p>也可以在此继续添加想要的插件。</p>
                  <p>全屏之后活脱脱就是一个桌面版本的 VS Code！</p>
                  <p>唯一不是很方便的就是在里面跑一些 Web 服务，因为 Web 服务相当于在 Docker 里面运行的，不过不要紧，我们只需要在 Chart 里面增加几个端口映射就好了。</p>
                  <p>有了它，我在里面写了代码，切换了不同 PC，我不用再关心代码的同步问题了。另外我就可以一键给别人分配一个 Online 版本的 VS Code，别人写了代码之后也可以方便拿给我看问题，也方便直接给别人分享我写的代码和运行效果，简直不要太爽了！</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-07-01 23:42:06" itemprop="dateCreated datePublished" datetime="2021-07-01T23:42:06+08:00">2021-07-01</time>
                </span>
                <span id="/30023.html" class="post-meta-item leancloud_visitors" data-flag-title="爽爆了！我搞了一个网页版 VS Code" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>7.1k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>6 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30022.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> Python <i class="label-arrow"></i>
                  </a>
                  <a href="/30022.html" class="post-title-link" itemprop="url">作为一只爬虫，如何科学有效地处理短信验证码？</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>之前我们了解了一些验证码的处理流程，比如图形验证码、滑块验证码、点选验证码等等，但是这些验证码都有一种共同的特点，那就是这些验证码的处理流程通常只需要在 PC 上完成即可，比如图形验证码如果在 PC 上出现，那么在 PC 上直接验证通过就好了，所有的识别、验证输入的流程都是在 PC 上完成的。</p>
                  <p>但还有一种验证码和此种情况不同，那就是手机验证码，比如 PC 上需要输入手机号，然后短信验证码需要发到手机上，然后再在 PC 上把收到的验证码输入即可通过验证。</p>
                  <p>那遇到这种情况，我们如何才能将这个流程给自动化呢？</p>
                  <h2 id="验证码收发"><a href="#验证码收发" class="headerlink" title="验证码收发"></a>验证码收发</h2>
                  <p>通常来说，我们的自动化脚本会运行在 PC 上，比如打开一个网页，然后模拟输入手机号，然后点击获取验证码，接下来就需要输入验证码了。打开页面，输入手机号、点击获取验证码等流程我们可以非常容易地实现自动化，但是验证码被发送到手机上了，我们怎么能把它转到 PC 上呢？</p>
                  <p>为了自动化整个验证码收发的流程，这时候我们想要完成的就是——当手机收到一条短信的时候，它能够自动将短信转发到某处，比如一台远程服务器上或者直接发到 PC 上，在 PC 上我们可以通过一些方法再把短信获取下来并提取验证码的内容，然后自动化填充验证码即可。</p>
                  <p>那这里关键的部分其实就是怎样完成这两个步骤：</p>
                  <ul>
                    <li>
                      <p>如何监听手机收到了短信</p>
                    </li>
                    <li>
                      <p>如何将手机短信转发到想要的位置</p>
                    </li>
                  </ul>
                  <p>这两个步骤缺一不可，而且都需要在手机上完成。</p>
                  <p>解决思路自然很简单了，我们以 Android 手机为例，如果有 Android 开发经验的话，其实这两个功能实现起来还是蛮简单的。</p>
                  <blockquote>
                    <p>注意：这里我们仅仅简单介绍基本的思路，不会完全详细展开介绍具体的代码实现，感兴趣的话可以自行尝试。</p>
                  </blockquote>
                  <p>首先如何监听手机收到了短信呢？</p>
                  <p>在 Android 开发中，整体就分为三个必要环节：</p>
                  <ul>
                    <li>注册读取短信的权限：在一个 Android App 中，读取短信是需要特定的权限的，所以我们需要在 Andriod App 的 AndroidManifest.xml 中将读取短信的权限配置好，比如接收短信的权限配置如下：</li>
                  </ul>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">uses-permission</span> <span class="attr">android:name</span>=<span class="string">"android.permission.RECEIVE_SMS"</span>&gt;</span><span class="tag">&lt;/<span class="name">uses-permission</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <ul>
                    <li>注册广播事件：Android 有一个基本组件叫做 BroadcastReceiver，也就是广播接收者的意思，我们可以用它来监听来自系统的各种事件广播，比如系统电量不足的广播、系统来电的广播，当然系统收到短信的广播也就不在话下了。所以这就类似我们注册一个监听器，用来监听系统收到短信的事件。<br>比如这里我们可以同样在 AndroidManifest.xml 里面注册一个 BroadcastReceiver，叫做 SmsReciver：</li>
                  </ul>
                  <figure class="highlight xml">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="tag">&lt;<span class="name">receiver</span> <span class="attr">android:name</span>=<span class="string">".receive.SmsReciver"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">intent-filter</span> <span class="attr">android:priority</span>=<span class="string">"999"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">action</span> <span class="attr">android:name</span>=<span class="string">"android.provider.Telephony.SMS_RECEIVED"</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">intent-filter</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">receiver</span>&gt;</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <ul>
                    <li>实现短信广播接收：这里就需要我们真正实现短信接收的逻辑了，这里只需要实现一个 SmsReceiver 类来继承一个 BroadcastReceiver 然后实现其 onReceive 方法即可，其中 intent 参数里面便包含了我们想要的短信息内容，实现如下：</li>
                  </ul>
                  <figure class="highlight java">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SmsReciver</span> <span class="keyword">extends</span> <span class="title">BroadcastReceiver</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onReceive</span><span class="params">(Context context, Intent intent)</span> </span>&#123;</span><br><span class="line">        Bundle bundle = intent.getExtras();</span><br><span class="line">        SmsMessage msg = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">null</span> != bundle) &#123;</span><br><span class="line">            Object[] smsObj = (Object[]) bundle.get(<span class="string">"pdus"</span>);</span><br><span class="line">            <span class="keyword">for</span> (Object object : smsObj) &#123;</span><br><span class="line">                msg = SmsMessage.createFromPdu((<span class="keyword">byte</span>[]) object);</span><br><span class="line">                Log.e(<span class="string">"短信号码"</span>, <span class="string">""</span> + msg.getOriginatingAddress());</span><br><span class="line">                Log.e(<span class="string">"短信内容"</span>, <span class="string">""</span> + msg.getDisplayMessageBody());</span><br><span class="line">                Log.e(<span class="string">"短信时间"</span>, <span class="string">""</span> + msg.getTimestampMillis());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>如此一来，我们便实现了短信的接收。</p>
                  <p>短信收到之后，发送自然也就很简单了，比如服务器提供一个 API，我们通过请求该 API 即可实现数据的发送，这个通过 Android 的一些 HTTP 请求库就可以实现，比如 OkHttp 等构造一个 HTTP 请求即可，这里就不再赘述了。</p>
                  <p>不过总的来说，整个流程下来其实还需要花费一些开发成本的，对于如此常用的功能，有没有现成的解决方案呢？自然是有的。我们可以借助于于一些开源实现，我们就没必要重复造轮子了。</p>
                  <p>这里我们就介绍一个开源软件，叫做 SmsForwarder，中文翻译过来叫做短信转发器，其 GitHub 仓库地址为：<a href="https://github.com/pppscn/SmsForwarder。" target="_blank" rel="noopener">https://github.com/pppscn/SmsForwarder。</a></p>
                  <p>它的基本流程架构图如下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/u73dy.png" alt=""></p>
                  <p>架构图非常清晰，SmsForwarder 可以监听监听收到短信的事件，获取到短信的来源号码、接受卡槽、短信内容、接收时间等内容，然后将其通过一定的规则转发出去，支持转发到邮箱、微信群机器人、企业微信、Telegram 机器人、Webhook 等。</p>
                  <p>比如我们可以配置类似这样的规则，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/8jb9r.jpg" alt="转发规则"></p>
                  <p>比如当手机号符合一定的规则就转发到 QQ 邮箱，比如内容包含“报警”就转发到阿里企业邮箱，比如内容开头是“测试”就发动给叫做 TSMS 的 Webhook。</p>
                  <p>其中QQ邮箱、阿里企业邮箱都是我们已经配置好的发送方，都属于邮箱类型，TSMS 也是一种发送方，属于 Webhook 类型，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/5deok.jpg" alt="发送方"></p>
                  <p>我们也可以点击添加发送方按钮来添加对应的发送方，比如添加邮箱的发送方，我们可以设置 SMTP 配置下发件邮箱、SMTP 服务器、SMTP 端口、授权密码等内容：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/vdqay.jpg" alt="添加/编辑发送方邮箱"></p>
                  <p>设置 Webhook 我们可以选择是 GET 还是 POST 请求，然后填入对应的 URL、密钥等内容：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/7vctb.jpg" alt="添加/编辑发送方网页通知"></p>
                  <p>设置转发规则页面如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/9gu5c.jpg" alt="支持正则匹配规则 &amp; 支持卡槽匹配规则"></p>
                  <p>比如这里我们可以选择匹配卡槽、匹配的字段、匹配的模式，还可以配置正则来设置匹配的值，这里就配置了尾号是 4566 的手机号来执行一定的发送操作，收到的短信会发送到钉钉这个发送方。</p>
                  <h2 id="实战演示"><a href="#实战演示" class="headerlink" title="实战演示"></a>实战演示</h2>
                  <p>比如这里我们来尝试下，这里我们用 Flask 写一个 API，实现如下：</p>
                  <figure class="highlight python">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, request, jsonify</span><br><span class="line"><span class="keyword">from</span> loguru <span class="keyword">import</span> logger</span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route('/sms', methods=['POST'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">receive</span><span class="params">()</span>:</span></span><br><span class="line">    sms_content = request.form.get(<span class="string">'content'</span>)</span><br><span class="line">    logger.debug(<span class="string">f'received <span class="subst">&#123;sms_content&#125;</span>'</span>)</span><br><span class="line">    <span class="comment"># parse content and save to db or mq</span></span><br><span class="line">    <span class="keyword">return</span> jsonify(status=<span class="string">'success'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    app.run(debug=<span class="literal">True</span>)</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>代码很简单，这里设置了一个路由，接收 POST 请求，然后读取了 Request 表单的内容，其中 content 就是短信的详情内容，然后将其打印出来。</p>
                  <p>我们将代码保存为 server.py，然后将其运行起来：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">python3 server.py</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果输出如下：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">* Debug mode: on</span><br><span class="line">* Running on http:&#x2F;&#x2F;127.0.0.1:5000&#x2F; (Press CTRL+C to quit)</span><br><span class="line">* Restarting with stat</span><br><span class="line">* Debugger is active!</span><br><span class="line">* Debugger PIN: 269-657-055</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>为了方便测试，我们可以用 Ngrok 将该服务暴露到公网：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">ngrok http 5000</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <blockquote>
                    <p>注意：Ngrok 可以方便地将任何非公网的服务暴露到公网访问，并配置特定的临时二级域名，但一个域名有时长限制，所以通常仅供测试使用。试用前请先安装 Ngrok，具体可以参考 <a href="https://ngrok.com/。" target="_blank" rel="noopener">https://ngrok.com/。</a></p>
                  </blockquote>
                  <p>运行之后，可以看到输入结果如下：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">Session Status                online                                                                                                   </span><br><span class="line">Session Expires               1 hour, 59 minutes                                                                                       </span><br><span class="line">Update                        update available (version 2.3.40, Ctrl-U to update)                                                      </span><br><span class="line">Version                       2.3.35                                                                                                   </span><br><span class="line">Region                        United States (us)                                                                                       </span><br><span class="line">Web Interface                 http:&#x2F;&#x2F;127.0.0.1:4040                                                                                    </span><br><span class="line">Forwarding                    http:&#x2F;&#x2F;1259539cb974.ngrok.io -&gt; http:&#x2F;&#x2F;localhost:5000                                                    </span><br><span class="line">Forwarding                    https:&#x2F;&#x2F;1259539cb974.ngrok.io -&gt; http:&#x2F;&#x2F;localhost:5000                                                   </span><br><span class="line">                                                                                                                                       </span><br><span class="line">Connections                   ttl     opn     rt1     rt5     p50     p90                                                              </span><br><span class="line">                              9       0       0.00    0.00    0.00    0.00</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这里我们可以看到 Ngrok 为我们配置了一个公网地址，比如访问 <a href="https://1259539cb974.ngrok.io" target="_blank" rel="noopener">https://1259539cb974.ngrok.io</a> 即相当于访问了我们本地的 <a href="http://localhost:5000" target="_blank" rel="noopener">http://localhost:5000</a> 服务，这样手机上只需要配置这个地址即可将数据发送到 PC 了。</p>
                  <p>接下来我们手机上打开 SmsForder，添加一个 Webhook 类型的发送方，配置如下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/p4zv5.jpg" alt=""></p>
                  <p>这里 Server 的地址我们就直接设置了刚才 Ngrok 提供的公网地址了，记得 URL 路径后面加上 sms。</p>
                  <p>接着我们添加一个转发规则：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/a706u.png" alt=""></p>
                  <p>这里我们设置了内容匹配规则，比如匹配到内容开头为测试的时候，那就将短信内容转发到 Webhook 这个发送方，即发送到我们刚刚搭建的 Flask 服务器上。</p>
                  <p>OK，配置完成之后，然后我们给该手机尝试发送一个验证码，内容如下：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">测试验证码593722，一分钟有效。</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>这时候就可以发现刚才的 Flask 服务器接收结果是这样的：</p>
                  <figure class="highlight plain">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line">received +8617xxxxxxxx</span><br><span class="line">测试验证码593722，一分钟有效。</span><br><span class="line">SIM2_China Unicom_</span><br><span class="line">2021-03-27 18:47:54</span><br><span class="line">SM-G9860</span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>可以看到刚才验证码的内容就成功由手机发送到 PC 了，接着我们便可以对此消息进行解析和处理，然后存入数据库或者消息队列即可。爬虫一端监听消息队列或者数据库改动即可将其填写并进行一些模拟登录操作了，该步骤就不再赘述了。</p>
                  <h2 id="批量收发"><a href="#批量收发" class="headerlink" title="批量收发"></a>批量收发</h2>
                  <p>当然以上只针对于一部手机的情况，如果我们有大量的手机和手机卡，我们可以实现手机的群控处理，比如统一安装短信接收软件，统一配置相同的转发规则，从而实现大量手机号验证码的接收和处理。</p>
                  <p>比如一个群控系统就是这样的：</p>
                  <h2 id="卡池"><a href="#卡池" class="headerlink" title="卡池"></a>卡池</h2>
                  <p>当然还有更专业的解决方案，比如有专业的手机卡池，配合以专业的软件设备实现短信的监听。</p>
                  <p>比如如下的设备支持插 128 张 SIM 卡，就可以实现同时监听 128 个手机号的验证码，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/fjrck.png" alt=""></p>
                  <p>具体的技术这里不再阐述，详细可以自行查询相关的设备供应商。</p>
                  <h2 id="接码平台"><a href="#接码平台" class="headerlink" title="接码平台"></a>接码平台</h2>
                  <p>当然如上的方案成本还是比较高的，而且这些方案其实已经不限于简单接收短信验证码了，比如手机群控系统一般都会做手机群控爬虫，而卡池也可以用来做 4G/5G 蜂窝代理，如果仅仅做短信收发是可以的，但未免有些浪费了。</p>
                  <p>如果我们不想耗费过多成本想实现短信验证码的自动化，还有一种方案就是接码平台，其基本思路是这样的：</p>
                  <ul>
                    <li>
                      <p>平台会维护大量的手机号，并可能开放一些 API 或者提供网页供我们调用来获取手机号和查看短信的内容。</p>
                    </li>
                    <li>
                      <p>我们调用 API 或者爬取网页获取手机号，然后在对应的站点输入该手机号来获取验证码。</p>
                    </li>
                    <li>
                      <p>通过调用 API 或者爬取网页获取对应手机号短信的内容，并交由爬虫处理。</p>
                    </li>
                  </ul>
                  <p>具体的操作步骤这里就不再详细阐述了，这里简单列几个接码平台：</p>
                  <ul>
                    <li>
                      <p>番薯云：<a href="https://guanfangdiping.com/" target="_blank" rel="noopener">https://guanfangdiping.com/</a></p>
                    </li>
                    <li>
                      <p>云际云短信：<a href="https://yunjisms.xyz/" target="_blank" rel="noopener">https://yunjisms.xyz/</a></p>
                    </li>
                    <li>
                      <p>接码号：<a href="https://jiemahao.com/" target="_blank" rel="noopener">https://jiemahao.com/</a></p>
                    </li>
                    <li>
                      <p>KaKa 接码：<a href="http://www.kakasms.com/" target="_blank" rel="noopener">http://www.kakasms.com/</a></p>
                    </li>
                  </ul>
                  <p>由于接码平台管控比较严格，所以可能随时不可用，请自行搜集对应的平台进行使用。</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-06-27 18:41:06" itemprop="dateCreated datePublished" datetime="2021-06-27T18:41:06+08:00">2021-06-27</time>
                </span>
                <span id="/30022.html" class="post-meta-item leancloud_visitors" data-flag-title="作为一只爬虫，如何科学有效地处理短信验证码？" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>5.2k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>5 分钟</span>
                </span>
              </div>
            </article>
            <article itemscope itemtype="http://schema.org/Article" class="post-block index" lang="zh-CN">
              <link itemprop="mainEntityOfPage" href="https://cuiqingcai.com/30021.html">
              <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
                <meta itemprop="image" content="/images/avatar.png">
                <meta itemprop="name" content="崔庆才">
                <meta itemprop="description" content="崔庆才的个人站点，记录生活的瞬间，分享学习的心得。">
              </span>
              <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
                <meta itemprop="name" content="静觅">
              </span>
              <header class="post-header">
                <h2 class="post-title" itemprop="name headline">
                  <a class="label"> 技术杂谈 <i class="label-arrow"></i>
                  </a>
                  <a href="/30021.html" class="post-title-link" itemprop="url">什么？VS Code 里面还能找女朋友？</a>
                </h2>
              </header>
              <div class="post-body" itemprop="articleBody">
                <div class="thumb">
                  <img itemprop="contentUrl" class="random">
                </div>
                <div class="excerpt">
                  <p>
                  <p>VS Code 之大，简直是无奇不有啊！</p>
                  <p>这不，前几天我就发现了一个插件，用这个插件我们甚至可以在 VS Code 里面交友！就像一些交友软件一样，喜欢的右滑、不喜欢的左滑，互相喜欢的就匹配成功，然后就可以聊天！进而？？？</p>
                  <p>简直是太骚了啊！</p>
                  <p>究竟是何方神圣呢？</p>
                  <p>这个 VS Code 插件叫做 vsinder，什么意思？就是 VS Code + Tinder （一个国外交友软件）的简写，Logo 是这样的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411800262.png" alt=""></p>
                  <p>这爱心不能太明显了。</p>
                  <p>抱着好奇心，我在 VS Code 里面搜了一下，还真有，而且现在已经 3w+ 次安装了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411843658.png" alt=""></p>
                  <p>那就索性来试试吧，点击 install，完了之后在 VS Code 的左侧就会出现一个爱心💗的入口，如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411871393.png" alt=""></p>
                  <p>点击一下，一上来就要求 Sign-in，这里是用的 GitHub 来登录的，点击之后会跳转到 vsinder 的 SSO 登录页面，GitHub 登录成功之后就会提示授权成功：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411890124.png" alt=""></p>
                  <p>回到 VS Code，这里就显示 GitHub 的个人信息了，它获取了我的 GitHub 头像、昵称、年龄等信息：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411930110.png" alt=""></p>
                  <p>当然我们也可以点击 edit profile 来修改自己的个人信息，点击之后如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411944285.png" alt=""></p>
                  <p>这里可以填写昵称、个人简介、擅长的编程语言、生日等信息，生日是用来计算年龄的。</p>
                  <p>然后下面还有一个关键的信息，就是你要在这里找什么人？一个是 love 一个是 friendship，如果选了 love，还会提示选择男的还是女的，还有年龄等等：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411961454.png" alt=""></p>
                  <p>比如这里我就果断选了 —— friendship！（逃</p>
                  <p>点击保存之后，还有另外一个入口就是 edit code pics，就是把自己觉得最牛逼的代码贴上，这样才会更多的人右滑对不对！？</p>
                  <p>我是写 Python 的，那我选什么好呢？</p>
                  <p>对了，那就选 Python 之禅了！大道至简，浑然天成！</p>
                  <p>Python 命令行输入：</p>
                  <figure class="highlight javascript">
                    <table>
                      <tr>
                        <td class="gutter">
                          <pre><span class="line">1</span><br></pre>
                        </td>
                        <td class="code">
                          <pre><span class="line"><span class="keyword">import</span> <span class="keyword">this</span></span><br></pre>
                        </td>
                      </tr>
                    </table>
                  </figure>
                  <p>运行结果如下：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624411982852.png" alt=""></p>
                  <p>这里我就复制一下，粘贴进去了，最多 600 字符，那这里我就直接截断了。</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412013775.png" alt=""></p>
                  <p>虽然这不是完完全全的 Python 代码，但把 Python 最核心的设计思想说出来了，是不是 Python 里面最牛逼的？（是！</p>
                  <p>我相信别人看到之后一定会疯狂 like 我的。</p>
                  <p>接下来保存下，然后我就点击 start swiping 开始滑动了！如图所示：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412050356.png" alt=""></p>
                  <p>一上来就滑到一个：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412066428.png" alt=""></p>
                  <p>这个人名字叫 Leon，23 岁，写了个代码是用来 walkDir 的，也就是遍历文件目录的，看简介似乎还是个俄语？俄罗斯人啊。</p>
                  <p>但是，这个一看就不太行，他不用 Python，如果用 Python 的话，直接用 glob 包不就解决的事吗？不行不行，果断点击 x。</p>
                  <p>这里还有快捷键，如果不喜欢可以点击键盘的左箭头，如果喜欢可以点击右箭头。</p>
                  <p>这里果断左箭头了！</p>
                  <p>又来了一个，这人写 Go 的：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412080228.png" alt=""></p>
                  <p>但是似乎就会个 Hello World，不行不行，果断还是左箭头了。</p>
                  <p>接下来一个 19 岁的孩子写了段 Java：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412100263.png" alt=""></p>
                  <p>还可以，写了一个 random 选择，随机抽取一句话返回，还行吧，那就 like 一下吧。</p>
                  <p>然而这时候，我发现了什么？一个聊天按钮？还有个 1？</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412118444.png" alt=""></p>
                  <p>我跟这个 19 岁的孩子匹配上了？？</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412141445.png" alt=""></p>
                  <p>点击头像还能聊天？</p>
                  <p>我发了一个：Your code is really cool! （其实也就是那样，小孩子嘛，稍微夸一夸啦</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412162279.png" alt=""></p>
                  <p>过了一会，也没理我。</p>
                  <p>估计可能时区不一样，还在睡觉呢吧？</p>
                  <p>算了我也不给他机会了，点击 ummatch 可以直接取消匹配，这样他就没法给我发消息了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412178826.png" alt=""></p>
                  <p>不一会我又匹配了一个写 Python的，但这会我忘记了他写的代码是什么样子的了怎么办呢？</p>
                  <p>不用担心，只需要点击他的昵称就又能看到他写的代码了：</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412180371.png" alt=""></p>
                  <p>他写的是一个 numpy 的调用，看起来还不错的样子。</p>
                  <p>于是，后面的事情，我就不说了，我们当然是欢乐地聊起了 Python。（手动滑稽</p>
                  <p>有人说？这个真能找到对象吗？还真能！</p>
                  <p>这个插件的作者 Ben Awad 做完这个插件之后，录了个视频上传了 Youtube，现场演示了自己是怎么在这里面找对象的。</p>
                  <p>不仅仅是匹配到了妹子，而且更牛逼的是他仅仅通过几句聊天就轻松拿到了电话号码？？？</p>
                  <p><img src="https://qiniu.cuiqingcai.com/1624412181004.png" alt=""></p>
                  <p>大师！</p>
                  <p>不愧是大师啊！</p>
                  <p>相信你也能行的，来试试吧～</p>
                  <p>更多精彩内容，请关注我的公众号「进击的 Coder」和「崔庆才丨静觅」。</p>
                  </p>
                </div>
              </div>
              <div class="post-meta">
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-user"></i>
                  </span>
                  <span class="post-meta-item-text">作者</span>
                  <span><a href="/authors/崔庆才" class="author" itemprop="url" rel="index">崔庆才</a></span>
                </span>
                <span class="post-meta-item">
                  <span class="post-meta-item-icon">
                    <i class="far fa-calendar"></i>
                  </span>
                  <span class="post-meta-item-text">发表于</span>
                  <time title="创建时间：2021-06-21 23:10:09" itemprop="dateCreated datePublished" datetime="2021-06-21T23:10:09+08:00">2021-06-21</time>
                </span>
                <span id="/30021.html" class="post-meta-item leancloud_visitors" data-flag-title="什么？VS Code 里面还能找女朋友？" title="阅读次数">
                  <span class="post-meta-item-icon">
                    <i class="fa fa-eye"></i>
                  </span>
                  <span class="post-meta-item-text">阅读次数：</span>
                  <span class="leancloud-visitors-count"></span>
                </span>
                <span class="post-meta-item" title="本文字数">
                  <span class="post-meta-item-icon">
                    <i class="far fa-file-word"></i>
                  </span>
                  <span class="post-meta-item-text">本文字数：</span>
                  <span>1.6k</span>
                </span>
                <span class="post-meta-item" title="阅读时长">
                  <span class="post-meta-item-icon">
                    <i class="far fa-clock"></i>
                  </span>
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                  <span>1 分钟</span>
                </span>
              </div>
            </article>
            <script>
              document.querySelectorAll('.random').forEach(item => item.src = "https://picsum.photos/id/" + Math.floor(Math.random() * Math.floor(300)) + "/200/133")

            </script>
            <nav class="pagination">
              <a class="extend prev" rel="prev" href="/page/3/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><span class="space">&hellip;</span><a class="page-number" href="/page/31/">31</a><a class="extend next" rel="next" href="/page/5/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
            </nav>
          </div>
          <script>
            window.addEventListener('tabs:register', () =>
            {
              let
              {
                activeClass
              } = CONFIG.comments;
              if (CONFIG.comments.storage)
              {
                activeClass = localStorage.getItem('comments_active') || activeClass;
              }
              if (activeClass)
              {
                let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
                if (activeTab)
                {
                  activeTab.click();
                }
              }
            });
            if (CONFIG.comments.storage)
            {
              window.addEventListener('tabs:click', event =>
              {
                if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
                let commentClass = event.target.classList[1];
                localStorage.setItem('comments_active', commentClass);
              });
            }

          </script>
        </div>
        <div class="toggle sidebar-toggle">
          <span class="toggle-line toggle-line-first"></span>
          <span class="toggle-line toggle-line-middle"></span>
          <span class="toggle-line toggle-line-last"></span>
        </div>
        <aside class="sidebar">
          <div class="sidebar-inner">
            <ul class="sidebar-nav motion-element">
              <li class="sidebar-nav-toc"> 文章目录 </li>
              <li class="sidebar-nav-overview"> 站点概览 </li>
            </ul>
            <!--noindex-->
            <div class="post-toc-wrap sidebar-panel">
            </div>
            <!--/noindex-->
            <div class="site-overview-wrap sidebar-panel">
              <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
                <img class="site-author-image" itemprop="image" alt="崔庆才" src="/images/avatar.png">
                <p class="site-author-name" itemprop="name">崔庆才</p>
                <div class="site-description" itemprop="description">崔庆才的个人站点，记录生活的瞬间，分享学习的心得。</div>
              </div>
              <div class="site-state-wrap motion-element">
                <nav class="site-state">
                  <div class="site-state-item site-state-posts">
                    <a href="/archives/">
                      <span class="site-state-item-count">608</span>
                      <span class="site-state-item-name">日志</span>
                    </a>
                  </div>
                  <div class="site-state-item site-state-categories">
                    <a href="/categories/">
                      <span class="site-state-item-count">24</span>
                      <span class="site-state-item-name">分类</span></a>
                  </div>
                  <div class="site-state-item site-state-tags">
                    <a href="/tags/">
                      <span class="site-state-item-count">156</span>
                      <span class="site-state-item-name">标签</span></a>
                  </div>
                </nav>
              </div>
              <div class="links-of-author motion-element">
                <span class="links-of-author-item">
                  <a href="https://github.com/Germey" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;Germey" rel="noopener" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
                </span>
                <span class="links-of-author-item">
                  <a href="mailto:cqc@cuiqingcai.com.com" title="邮件 → mailto:cqc@cuiqingcai.com.com" rel="noopener" target="_blank"><i class="fa fa-envelope fa-fw"></i>邮件</a>
                </span>
                <span class="links-of-author-item">
                  <a href="https://weibo.com/cuiqingcai" title="微博 → https:&#x2F;&#x2F;weibo.com&#x2F;cuiqingcai" rel="noopener" target="_blank"><i class="fab fa-weibo fa-fw"></i>微博</a>
                </span>
                <span class="links-of-author-item">
                  <a href="https://www.zhihu.com/people/Germey" title="知乎 → https:&#x2F;&#x2F;www.zhihu.com&#x2F;people&#x2F;Germey" rel="noopener" target="_blank"><i class="fa fa-magic fa-fw"></i>知乎</a>
                </span>
              </div>
            </div>
            <div style=" width: 100%;" class="sidebar-panel sidebar-panel-image sidebar-panel-active">
              <a href="https://tutorial.lengyue.video/?coupon=12ef4b1a-a3db-11ea-bb37-0242ac130002_cqx_850" target="_blank" rel="noopener">
                <img src="https://qiniu.cuiqingcai.com/bco2a.png" style=" width: 100%;">
              </a>
            </div>
            <div style=" width: 100%;" class="sidebar-panel sidebar-panel-image sidebar-panel-active">
              <a href="http://www.ipidea.net/?utm-source=cqc&utm-keyword=?cqc" target="_blank" rel="noopener">
                <img src="https://qiniu.cuiqingcai.com/0ywun.png" style=" width: 100%;">
              </a>
            </div>
            <div class="sidebar-panel sidebar-panel-tags sidebar-panel-active">
              <h4 class="name"> 标签云 </h4>
              <div class="content">
                <a href="/tags/2048/" style="font-size: 10px;">2048</a> <a href="/tags/API/" style="font-size: 10px;">API</a> <a href="/tags/Bootstrap/" style="font-size: 11.25px;">Bootstrap</a> <a href="/tags/CDN/" style="font-size: 10px;">CDN</a> <a href="/tags/CQC/" style="font-size: 10px;">CQC</a> <a href="/tags/CSS/" style="font-size: 10px;">CSS</a> <a href="/tags/CSS-%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 10px;">CSS 反爬虫</a> <a href="/tags/CV/" style="font-size: 10px;">CV</a> <a href="/tags/Django/" style="font-size: 10px;">Django</a> <a href="/tags/Eclipse/" style="font-size: 11.25px;">Eclipse</a> <a href="/tags/FTP/" style="font-size: 10px;">FTP</a> <a href="/tags/Git/" style="font-size: 10px;">Git</a> <a href="/tags/GitHub/" style="font-size: 13.75px;">GitHub</a> <a href="/tags/HTML5/" style="font-size: 10px;">HTML5</a> <a href="/tags/Hexo/" style="font-size: 10px;">Hexo</a> <a href="/tags/IT/" style="font-size: 10px;">IT</a> <a href="/tags/JSP/" style="font-size: 10px;">JSP</a> <a href="/tags/JavaScript/" style="font-size: 10px;">JavaScript</a> <a href="/tags/K8s/" style="font-size: 10px;">K8s</a> <a href="/tags/LOGO/" style="font-size: 10px;">LOGO</a> <a href="/tags/Linux/" style="font-size: 10px;">Linux</a> <a href="/tags/MIUI/" style="font-size: 10px;">MIUI</a> <a href="/tags/MongoDB/" style="font-size: 10px;">MongoDB</a> <a href="/tags/Mysql/" style="font-size: 10px;">Mysql</a> <a href="/tags/NBA/" style="font-size: 10px;">NBA</a> <a href="/tags/PHP/" style="font-size: 11.25px;">PHP</a> <a href="/tags/PS/" style="font-size: 10px;">PS</a> <a href="/tags/Pathlib/" style="font-size: 10px;">Pathlib</a> <a href="/tags/PhantomJS/" style="font-size: 10px;">PhantomJS</a> <a href="/tags/Python/" style="font-size: 15px;">Python</a> <a href="/tags/Python3/" style="font-size: 12.5px;">Python3</a> <a href="/tags/Pythonic/" style="font-size: 10px;">Pythonic</a> <a href="/tags/QQ/" style="font-size: 10px;">QQ</a> <a href="/tags/Redis/" style="font-size: 10px;">Redis</a> <a href="/tags/SAE/" style="font-size: 10px;">SAE</a> <a href="/tags/SSH/" style="font-size: 10px;">SSH</a> <a href="/tags/SVG/" style="font-size: 10px;">SVG</a> <a href="/tags/Scrapy/" style="font-size: 10px;">Scrapy</a> <a href="/tags/Scrapy-redis/" style="font-size: 10px;">Scrapy-redis</a> <a href="/tags/Scrapy%E5%88%86%E5%B8%83%E5%BC%8F/" style="font-size: 10px;">Scrapy分布式</a> <a href="/tags/Selenium/" style="font-size: 10px;">Selenium</a> <a href="/tags/TKE/" style="font-size: 10px;">TKE</a> <a href="/tags/Ubuntu/" style="font-size: 11.25px;">Ubuntu</a> <a href="/tags/VS-Code/" style="font-size: 10px;">VS Code</a> <a href="/tags/Vs-Code/" style="font-size: 10px;">Vs Code</a> <a href="/tags/Vue/" style="font-size: 11.25px;">Vue</a> <a href="/tags/Webpack/" style="font-size: 10px;">Webpack</a> <a href="/tags/Windows/" style="font-size: 10px;">Windows</a> <a href="/tags/Winpcap/" style="font-size: 10px;">Winpcap</a> <a href="/tags/WordPress/" style="font-size: 13.75px;">WordPress</a> <a href="/tags/Youtube/" style="font-size: 11.25px;">Youtube</a> <a href="/tags/android/" style="font-size: 10px;">android</a> <a href="/tags/ansible/" style="font-size: 10px;">ansible</a> <a href="/tags/cocos2d-x/" style="font-size: 10px;">cocos2d-x</a> <a href="/tags/e6/" style="font-size: 10px;">e6</a> <a href="/tags/fitvids/" style="font-size: 10px;">fitvids</a> <a href="/tags/git/" style="font-size: 11.25px;">git</a> <a href="/tags/json/" style="font-size: 10px;">json</a> <a href="/tags/js%E9%80%86%E5%90%91/" style="font-size: 10px;">js逆向</a> <a href="/tags/kubernetes/" style="font-size: 10px;">kubernetes</a> <a href="/tags/log/" style="font-size: 10px;">log</a> <a href="/tags/logging/" style="font-size: 10px;">logging</a> <a href="/tags/matlab/" style="font-size: 11.25px;">matlab</a> <a href="/tags/python/" style="font-size: 20px;">python</a> <a href="/tags/pytube/" style="font-size: 11.25px;">pytube</a> <a href="/tags/pywin32/" style="font-size: 10px;">pywin32</a> <a href="/tags/style/" style="font-size: 10px;">style</a> <a href="/tags/tomcat/" style="font-size: 10px;">tomcat</a> <a href="/tags/ubuntu/" style="font-size: 10px;">ubuntu</a> <a href="/tags/uwsgi/" style="font-size: 10px;">uwsgi</a> <a href="/tags/vsftpd/" style="font-size: 10px;">vsftpd</a> <a href="/tags/wamp/" style="font-size: 10px;">wamp</a> <a href="/tags/wineQQ/" style="font-size: 10px;">wineQQ</a> <a href="/tags/%E4%B8%83%E7%89%9B/" style="font-size: 11.25px;">七牛</a> <a href="/tags/%E4%B8%8A%E6%B5%B7/" style="font-size: 10px;">上海</a> <a href="/tags/%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99/" style="font-size: 10px;">个人网站</a> <a href="/tags/%E4%B8%BB%E9%A2%98/" style="font-size: 10px;">主题</a> <a href="/tags/%E4%BA%91%E4%BA%A7%E5%93%81/" style="font-size: 10px;">云产品</a> <a href="/tags/%E4%BA%91%E5%AD%98%E5%82%A8/" style="font-size: 10px;">云存储</a> <a href="/tags/%E4%BA%AC%E4%B8%9C%E4%BA%91/" style="font-size: 10px;">京东云</a> <a href="/tags/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/" style="font-size: 12.5px;">人工智能</a> <a href="/tags/%E4%BB%A3%E7%90%86/" style="font-size: 10px;">代理</a> <a href="/tags/%E4%BB%A3%E7%A0%81/" style="font-size: 10px;">代码</a> <a href="/tags/%E4%BB%A3%E7%A0%81%E5%88%86%E4%BA%AB%E5%9B%BE/" style="font-size: 10px;">代码分享图</a> <a href="/tags/%E4%BC%98%E5%8C%96/" style="font-size: 10px;">优化</a> <a href="/tags/%E4%BD%8D%E8%BF%90%E7%AE%97/" style="font-size: 10px;">位运算</a> <a href="/tags/%E5%85%AC%E4%BC%97%E5%8F%B7/" style="font-size: 10px;">公众号</a> <a href="/tags/%E5%88%86%E4%BA%AB/" style="font-size: 10px;">分享</a> <a href="/tags/%E5%88%86%E5%B8%83%E5%BC%8F/" style="font-size: 10px;">分布式</a> <a href="/tags/%E5%88%9B%E4%B8%9A/" style="font-size: 10px;">创业</a> <a href="/tags/%E5%89%8D%E7%AB%AF/" style="font-size: 12.5px;">前端</a> <a href="/tags/%E5%8D%9A%E5%AE%A2/" style="font-size: 10px;">博客</a> <a href="/tags/%E5%8E%9F%E7%94%9FAPP/" style="font-size: 10px;">原生APP</a> <a href="/tags/%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 12.5px;">反爬虫</a> <a href="/tags/%E5%91%BD%E4%BB%A4/" style="font-size: 10px;">命令</a> <a href="/tags/%E5%93%8D%E5%BA%94%E5%BC%8F%E5%B8%83%E5%B1%80/" style="font-size: 10px;">响应式布局</a> <a href="/tags/%E5%9E%83%E5%9C%BE%E9%82%AE%E4%BB%B6/" style="font-size: 10px;">垃圾邮件</a> <a href="/tags/%E5%9F%9F%E5%90%8D%E7%BB%91%E5%AE%9A/" style="font-size: 10px;">域名绑定</a> <a href="/tags/%E5%A4%8D%E7%9B%98/" style="font-size: 10px;">复盘</a> <a href="/tags/%E5%A4%A7%E4%BC%97%E7%82%B9%E8%AF%84/" style="font-size: 10px;">大众点评</a> <a href="/tags/%E5%AD%97%E4%BD%93%E5%8F%8D%E7%88%AC%E8%99%AB/" style="font-size: 10px;">字体反爬虫</a> <a href="/tags/%E5%AD%97%E7%AC%A6%E9%97%AE%E9%A2%98/" style="font-size: 10px;">字符问题</a> <a href="/tags/%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95/" style="font-size: 10px;">学习方法</a> <a href="/tags/%E5%AE%89%E5%8D%93/" style="font-size: 10px;">安卓</a> <a href="/tags/%E5%AE%9E%E7%94%A8/" style="font-size: 10px;">实用</a> <a href="/tags/%E5%B0%81%E9%9D%A2/" style="font-size: 10px;">封面</a> <a href="/tags/%E5%B4%94%E5%BA%86%E6%89%8D/" style="font-size: 18.75px;">崔庆才</a> <a href="/tags/%E5%B7%A5%E5%85%B7/" style="font-size: 12.5px;">工具</a> <a href="/tags/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/" style="font-size: 10px;">开发工具</a> <a href="/tags/%E5%BE%AE%E8%BD%AF/" style="font-size: 10px;">微软</a> <a href="/tags/%E6%80%9D%E8%80%83/" style="font-size: 10px;">思考</a> <a href="/tags/%E6%89%8B%E6%9C%BA%E8%AE%BF%E9%97%AE/" style="font-size: 10px;">手机访问</a> <a href="/tags/%E6%95%99%E7%A8%8B/" style="font-size: 10px;">教程</a> <a href="/tags/%E6%95%99%E8%82%B2/" style="font-size: 10px;">教育</a> <a href="/tags/%E6%96%B0%E4%B9%A6/" style="font-size: 12.5px;">新书</a> <a href="/tags/%E6%96%B9%E6%B3%95%E8%AE%BA/" style="font-size: 10px;">方法论</a> <a href="/tags/%E6%97%85%E6%B8%B8/" style="font-size: 10px;">旅游</a> <a href="/tags/%E6%97%A5%E5%BF%97/" style="font-size: 10px;">日志</a> <a href="/tags/%E6%9A%97%E6%97%B6%E9%97%B4/" style="font-size: 10px;">暗时间</a> <a href="/tags/%E6%9D%9C%E5%85%B0%E7%89%B9/" style="font-size: 11.25px;">杜兰特</a> <a href="/tags/%E6%A1%8C%E9%9D%A2/" style="font-size: 10px;">桌面</a> <a href="/tags/%E6%AD%8C%E5%8D%95/" style="font-size: 10px;">歌单</a> <a href="/tags/%E6%B1%9F%E5%8D%97/" style="font-size: 10px;">江南</a> <a href="/tags/%E6%B8%B8%E6%88%8F/" style="font-size: 10px;">游戏</a> <a href="/tags/%E7%84%A6%E8%99%91/" style="font-size: 10px;">焦虑</a> <a href="/tags/%E7%88%AC%E8%99%AB/" style="font-size: 16.25px;">爬虫</a> <a href="/tags/%E7%88%AC%E8%99%AB%E4%B9%A6%E7%B1%8D/" style="font-size: 11.25px;">爬虫书籍</a> <a href="/tags/%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F/" style="font-size: 10px;">环境变量</a> <a href="/tags/%E7%94%9F%E6%B4%BB%E7%AC%94%E8%AE%B0/" style="font-size: 10px;">生活笔记</a> <a href="/tags/%E7%99%BB%E5%BD%95/" style="font-size: 10px;">登录</a> <a href="/tags/%E7%9F%A5%E4%B9%8E/" style="font-size: 10px;">知乎</a> <a href="/tags/%E7%9F%AD%E4%BF%A1/" style="font-size: 10px;">短信</a> <a href="/tags/%E7%9F%AD%E4%BF%A1%E9%AA%8C%E8%AF%81%E7%A0%81/" style="font-size: 10px;">短信验证码</a> <a href="/tags/%E7%AC%94%E8%AE%B0%E8%BD%AF%E4%BB%B6/" style="font-size: 10px;">笔记软件</a> <a href="/tags/%E7%AF%AE%E7%BD%91/" style="font-size: 10px;">篮网</a> <a href="/tags/%E7%BA%B8%E5%BC%A0/" style="font-size: 10px;">纸张</a> <a href="/tags/%E7%BB%84%E4%BB%B6/" style="font-size: 10px;">组件</a> <a href="/tags/%E7%BD%91%E7%AB%99/" style="font-size: 10px;">网站</a> <a href="/tags/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/" style="font-size: 11.25px;">网络爬虫</a> <a href="/tags/%E7%BE%8E%E5%AD%A6/" style="font-size: 10px;">美学</a> <a href="/tags/%E8%82%89%E5%A4%B9%E9%A6%8D/" style="font-size: 10px;">肉夹馍</a> <a href="/tags/%E8%85%BE%E8%AE%AF%E4%BA%91/" style="font-size: 10px;">腾讯云</a> <a href="/tags/%E8%87%AA%E5%BE%8B/" style="font-size: 10px;">自律</a> <a href="/tags/%E8%A5%BF%E5%B0%91%E7%88%B7/" style="font-size: 10px;">西少爷</a> <a href="/tags/%E8%A7%86%E9%A2%91/" style="font-size: 10px;">视频</a> <a href="/tags/%E8%B0%B7%E6%AD%8C%E9%AA%8C%E8%AF%81%E7%A0%81/" style="font-size: 10px;">谷歌验证码</a> <a href="/tags/%E8%BF%90%E8%90%A5/" style="font-size: 10px;">运营</a> <a href="/tags/%E8%BF%9C%E7%A8%8B/" style="font-size: 10px;">远程</a> <a href="/tags/%E9%80%86%E5%90%91/" style="font-size: 10px;">逆向</a> <a href="/tags/%E9%85%8D%E7%BD%AE/" style="font-size: 10px;">配置</a> <a href="/tags/%E9%87%8D%E8%A3%85/" style="font-size: 10px;">重装</a> <a href="/tags/%E9%98%BF%E6%9D%9C/" style="font-size: 10px;">阿杜</a> <a href="/tags/%E9%9D%99%E8%A7%85/" style="font-size: 17.5px;">静觅</a> <a href="/tags/%E9%A2%A0%E8%A6%86/" style="font-size: 10px;">颠覆</a> <a href="/tags/%E9%A3%9E%E4%BF%A1/" style="font-size: 10px;">飞信</a> <a href="/tags/%E9%B8%BF%E8%92%99/" style="font-size: 10px;">鸿蒙</a>
              </div>
              <script>
                const tagsColors = ['#00a67c', '#5cb85c', '#d9534f', '#567e95', '#b37333', '#f4843d', '#15a287']
                const tagsElements = document.querySelectorAll('.sidebar-panel-tags .content a')
                tagsElements.forEach((item) =>
                {
                  item.style.backgroundColor = tagsColors[Math.floor(Math.random() * tagsColors.length)]
                })

              </script>
            </div>
            <div class="sidebar-panel sidebar-panel-categories sidebar-panel-active">
              <h4 class="name"> 分类 </h4>
              <div class="content">
                <ul class="category-list">
                  <li class="category-list-item"><a class="category-list-link" href="/categories/C-C/">C/C++</a><span class="category-list-count">23</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/HTML/">HTML</a><span class="category-list-count">14</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Java/">Java</a><span class="category-list-count">5</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/JavaScript/">JavaScript</a><span class="category-list-count">26</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a><span class="category-list-count">15</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Markdown/">Markdown</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Net/">Net</a><span class="category-list-count">4</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Other/">Other</a><span class="category-list-count">39</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/PHP/">PHP</a><span class="category-list-count">27</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Paper/">Paper</a><span class="category-list-count">2</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/Python/">Python</a><span class="category-list-count">261</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/TypeScript/">TypeScript</a><span class="category-list-count">2</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E5%B1%95%E7%A4%BA/">个人展示</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E6%97%A5%E8%AE%B0/">个人日记</a><span class="category-list-count">9</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E8%AE%B0%E5%BD%95/">个人记录</a><span class="category-list-count">4</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E4%B8%AA%E4%BA%BA%E9%9A%8F%E7%AC%94/">个人随笔</a><span class="category-list-count">15</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/">安装配置</a><span class="category-list-count">59</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E6%8A%80%E6%9C%AF%E6%9D%82%E8%B0%88/">技术杂谈</a><span class="category-list-count">88</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E6%9C%AA%E5%88%86%E7%B1%BB/">未分类</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E7%94%9F%E6%B4%BB%E7%AC%94%E8%AE%B0/">生活笔记</a><span class="category-list-count">1</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E7%A6%8F%E5%88%A9%E4%B8%93%E5%8C%BA/">福利专区</a><span class="category-list-count">6</span></li>
                  <li class="category-list-item"><a class="category-list-link" href="/categories/%E8%81%8C%E4%BD%8D%E6%8E%A8%E8%8D%90/">职位推荐</a><span class="category-list-count">2</span></li>
                </ul>
              </div>
            </div>
            <div class="sidebar-panel sidebar-panel-friends sidebar-panel-active">
              <h4 class="name"> 友情链接 </h4>
              <ul class="friends">
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/j2dub.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.findhao.net/" target="_blank" rel="noopener">FindHao</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ou6mm.jpg">
                  </span>
                  <span class="link">
                    <a href="https://diygod.me/" target="_blank" rel="noopener">DIYgod</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/6apxu.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.51dev.com/" target="_blank" rel="noopener">IT技术社区</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.jankl.com/img/titleshu.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.jankl.com/" target="_blank" rel="noopener">liberalist</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/bqlbs.png">
                  </span>
                  <span class="link">
                    <a href="http://www.urselect.com/" target="_blank" rel="noopener">优社电商</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/8s88c.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.yuanrenxue.com/" target="_blank" rel="noopener">猿人学</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/2wgg5.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.yunlifang.cn/" target="_blank" rel="noopener">云立方</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/shwr6.png">
                  </span>
                  <span class="link">
                    <a href="http://lanbing510.info/" target="_blank" rel="noopener">冰蓝</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/blvoh.jpg">
                  </span>
                  <span class="link">
                    <a href="https://lengyue.me/" target="_blank" rel="noopener">冷月</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="http://qianxunclub.com/favicon.png">
                  </span>
                  <span class="link">
                    <a href="http://qianxunclub.com/" target="_blank" rel="noopener">千寻啊千寻</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/0044u.jpg">
                  </span>
                  <span class="link">
                    <a href="http://kodcloud.com/" target="_blank" rel="noopener">可道云</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ygnpn.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.kunkundashen.cn/" target="_blank" rel="noopener">坤坤大神</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/22uv1.png">
                  </span>
                  <span class="link">
                    <a href="http://www.cenchong.com/" target="_blank" rel="noopener">岑冲博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ev9kl.png">
                  </span>
                  <span class="link">
                    <a href="http://www.zxiaoji.com/" target="_blank" rel="noopener">张小鸡</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.503error.com/favicon.ico">
                  </span>
                  <span class="link">
                    <a href="https://www.503error.com/" target="_blank" rel="noopener">张志明个人博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/x714o.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.hubwiz.com/" target="_blank" rel="noopener">汇智网</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/129d8.png">
                  </span>
                  <span class="link">
                    <a href="https://www.bysocket.com/" target="_blank" rel="noopener">泥瓦匠BYSocket</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://www.xiongge.club/favicon.ico">
                  </span>
                  <span class="link">
                    <a href="https://www.xiongge.club/" target="_blank" rel="noopener">熊哥club</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/3w4fe.png">
                  </span>
                  <span class="link">
                    <a href="https://zerlong.com/" target="_blank" rel="noopener">知语</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/44hxf.png">
                  </span>
                  <span class="link">
                    <a href="http://redstonewill.com/" target="_blank" rel="noopener">红色石头</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/8g1fk.jpg">
                  </span>
                  <span class="link">
                    <a href="http://www.laodong.me/" target="_blank" rel="noopener">老董博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/wkaus.jpg">
                  </span>
                  <span class="link">
                    <a href="https://zhaoshuai.me/" target="_blank" rel="noopener">碎念</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/pgo0r.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.chenwenguan.com/" target="_blank" rel="noopener">陈文管的博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/kk82a.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.lxlinux.net/" target="_blank" rel="noopener">良许Linux教程网</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/lj0t2.jpg">
                  </span>
                  <span class="link">
                    <a href="https://tanqingbo.cn/" target="_blank" rel="noopener">IT码农</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/i8cdr.png">
                  </span>
                  <span class="link">
                    <a href="https://junyiseo.com/" target="_blank" rel="noopener">均益个人博客</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/chwv2.png">
                  </span>
                  <span class="link">
                    <a href="https://brucedone.com/" target="_blank" rel="noopener">大鱼的鱼塘</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/2y43o.png">
                  </span>
                  <span class="link">
                    <a href="http://bbs.nightteam.cn/" target="_blank" rel="noopener">夜幕爬虫安全论坛</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/zvc3w.jpg">
                  </span>
                  <span class="link">
                    <a href="https://www.weishidong.com/" target="_blank" rel="noopener">韦世东的技术专栏</a>
                  </span>
                </li>
                <li class="friend">
                  <span class="logo">
                    <img src="https://qiniu.cuiqingcai.com/ebudy.jpg">
                  </span>
                  <span class="link">
                    <a href="https://chuanjiabing.com/" target="_blank" rel="noopener">穿甲兵技术社区</a>
                  </span>
                </li>
              </ul>
            </div>
          </div>
        </aside>
        <div id="sidebar-dimmer"></div>
      </div>
    </main>
    <footer class="footer">
      <div class="footer-inner">
        <div class="copyright"> &copy; <span itemprop="copyrightYear">2021</span>
          <span class="with-love">
            <i class="fa fa-heart"></i>
          </span>
          <span class="author" itemprop="copyrightHolder">崔庆才丨静觅</span>
          <span class="post-meta-divider">|</span>
          <span class="post-meta-item-icon">
            <i class="fa fa-chart-area"></i>
          </span>
          <span title="站点总字数">2.6m</span>
          <span class="post-meta-divider">|</span>
          <span class="post-meta-item-icon">
            <i class="fa fa-coffee"></i>
          </span>
          <span title="站点阅读时长">39:54</span>
        </div>
        <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动 </div>
        <div class="beian"><a href="https://beian.miit.gov.cn/" rel="noopener" target="_blank">京ICP备18015597号-1 </a>
        </div>
        <script>
          (function ()
          {
            function leancloudSelector(url)
            {
              url = encodeURI(url);
              return document.getElementById(url).querySelector('.leancloud-visitors-count');
            }

            function addCount(Counter)
            {
              var visitors = document.querySelector('.leancloud_visitors');
              var url = decodeURI(visitors.id);
              var title = visitors.dataset.flagTitle;
              Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify(
              {
                url
              }))).then(response => response.json()).then((
              {
                results
              }) =>
              {
                if (results.length > 0)
                {
                  var counter = results[0];
                  leancloudSelector(url).innerText = counter.time + 1;
                  Counter('put', '/classes/Counter/' + counter.objectId,
                  {
                    time:
                    {
                      '__op': 'Increment',
                      'amount': 1
                    }
                  }).catch(error =>
                  {
                    console.error('Failed to save visitor count', error);
                  });
                }
                else
                {
                  Counter('post', '/classes/Counter',
                  {
                    title,
                    url,
                    time: 1
                  }).then(response => response.json()).then(() =>
                  {
                    leancloudSelector(url).innerText = 1;
                  }).catch(error =>
                  {
                    console.error('Failed to create', error);
                  });
                }
              }).catch(error =>
              {
                console.error('LeanCloud Counter Error', error);
              });
            }

            function showTime(Counter)
            {
              var visitors = document.querySelectorAll('.leancloud_visitors');
              var entries = [...visitors].map(element =>
              {
                return decodeURI(element.id);
              });
              Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify(
              {
                url:
                {
                  '$in': entries
                }
              }))).then(response => response.json()).then((
              {
                results
              }) =>
              {
                for (let url of entries)
                {
                  let target = results.find(item => item.url === url);
                  leancloudSelector(url).innerText = target ? target.time : 0;
                }
              }).catch(error =>
              {
                console.error('LeanCloud Counter Error', error);
              });
            }
            let
            {
              app_id,
              app_key,
              server_url
            } = {
              "enable": true,
              "app_id": "6X5dRQ0pnPWJgYy8SXOg0uID-gzGzoHsz",
              "app_key": "ziLDVEy73ne5HtFTiGstzHMS",
              "server_url": "https://6x5drq0p.lc-cn-n1-shared.com",
              "security": false
            };

            function fetchData(api_server)
            {
              var Counter = (method, url, data) =>
              {
                return fetch(`${api_server}/1.1${url}`,
                {
                  method,
                  headers:
                  {
                    'X-LC-Id': app_id,
                    'X-LC-Key': app_key,
                    'Content-Type': 'application/json',
                  },
                  body: JSON.stringify(data)
                });
              };
              if (CONFIG.page.isPost)
              {
                if (CONFIG.hostname !== location.hostname) return;
                addCount(Counter);
              }
              else if (document.querySelectorAll('.post-title-link').length >= 1)
              {
                showTime(Counter);
              }
            }
            let api_server = app_id.slice(-9) !== '-MdYXbMMI' ? server_url : `https://${app_id.slice(0, 8).toLowerCase()}.api.lncldglobal.com`;
            if (api_server)
            {
              fetchData(api_server);
            }
            else
            {
              fetch('https://app-router.leancloud.cn/2/route?appId=' + app_id).then(response => response.json()).then((
              {
                api_server
              }) =>
              {
                fetchData('https://' + api_server);
              });
            }
          })();

        </script>
      </div>
      <div class="footer-stat">
        <span id="cnzz_stat_icon_1279355174"></span>
        <script type="text/javascript">
          document.write(unescape("%3Cspan id='cnzz_stat_icon_1279355174'%3E%3C/span%3E%3Cscript src='https://v1.cnzz.com/z_stat.php%3Fid%3D1279355174%26online%3D1%26show%3Dline' type='text/javascript'%3E%3C/script%3E"));

        </script>
      </div>
    </footer>
  </div>
  <script src="//cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js"></script>
  <script src="/js/utils.js"></script>
  <script src="/.js"></script>
  <script src="/js/schemes/pisces.js"></script>
  <script src="/.js"></script>
  <script src="/js/next-boot.js"></script>
  <script src="/.js"></script>
  <script>
    (function ()
    {
      var canonicalURL, curProtocol;
      //Get the <link> tag
      var x = document.getElementsByTagName("link");
      //Find the last canonical URL
      if (x.length > 0)
      {
        for (i = 0; i < x.length; i++)
        {
          if (x[i].rel.toLowerCase() == 'canonical' && x[i].href)
          {
            canonicalURL = x[i].href;
          }
        }
      }
      //Get protocol
      if (!canonicalURL)
      {
        curProtocol = window.location.protocol.split(':')[0];
      }
      else
      {
        curProtocol = canonicalURL.split(':')[0];
      }
      //Get current URL if the canonical URL does not exist
      if (!canonicalURL) canonicalURL = window.location.href;
      //Assign script content. Replace current URL with the canonical URL
      ! function ()
      {
        var e = /([http|https]:\/\/[a-zA-Z0-9\_\.]+\.baidu\.com)/gi,
          r = canonicalURL,
          t = document.referrer;
        if (!e.test(r))
        {
          var n = (String(curProtocol).toLowerCase() === 'https') ? "https://sp0.baidu.com/9_Q4simg2RQJ8t7jm9iCKT-xh_/s.gif" : "//api.share.baidu.com/s.gif";
          t ? (n += "?r=" + encodeURIComponent(document.referrer), r && (n += "&l=" + r)) : r && (n += "?l=" + r);
          var i = new Image;
          i.src = n
        }
      }(window);
    })();

  </script>
  <script src="/js/local-search.js"></script>
  <script src="/.js"></script>
</body>

</html>
